2016-06-02 20:01:19 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "KeyUtil.h"
|
|
|
|
|
|
|
|
#include <iomanip>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
2023-02-22 03:28:28 +01:00
|
|
|
#include <thread>
|
2016-06-02 20:01:19 +02:00
|
|
|
|
2019-09-30 22:05:58 +02:00
|
|
|
#include <fcntl.h>
|
2019-12-17 00:55:12 +01:00
|
|
|
#include <linux/fscrypt.h>
|
2016-06-02 20:01:19 +02:00
|
|
|
#include <openssl/sha.h>
|
2019-09-30 22:05:58 +02:00
|
|
|
#include <sys/ioctl.h>
|
2016-06-02 20:01:19 +02:00
|
|
|
|
|
|
|
#include <android-base/file.h>
|
|
|
|
#include <android-base/logging.h>
|
|
|
|
|
|
|
|
#include "KeyStorage.h"
|
|
|
|
#include "Utils.h"
|
|
|
|
|
|
|
|
namespace android {
|
|
|
|
namespace vold {
|
|
|
|
|
2020-04-06 04:34:31 +02:00
|
|
|
using android::fscrypt::EncryptionOptions;
|
|
|
|
using android::fscrypt::EncryptionPolicy;
|
|
|
|
|
2023-02-22 03:28:28 +01:00
|
|
|
// This must be acquired before calling fscrypt ioctls that operate on keys.
|
|
|
|
// This prevents race conditions between evicting and reinstalling keys.
|
|
|
|
static std::mutex fscrypt_keyring_mutex;
|
|
|
|
|
2020-02-12 20:04:05 +01:00
|
|
|
const KeyGeneration neverGen() {
|
|
|
|
return KeyGeneration{0, false, false};
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool randomKey(size_t size, KeyBuffer* key) {
|
|
|
|
*key = KeyBuffer(size);
|
2017-08-01 18:15:53 +02:00
|
|
|
if (ReadRandomBytes(key->size(), key->data()) != 0) {
|
2016-06-02 20:01:19 +02:00
|
|
|
// TODO status_t plays badly with PLOG, fix it.
|
|
|
|
LOG(ERROR) << "Random read failed";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-02-12 20:04:05 +01:00
|
|
|
bool generateStorageKey(const KeyGeneration& gen, KeyBuffer* key) {
|
2021-11-06 02:57:49 +01:00
|
|
|
if (!gen.allow_gen) {
|
|
|
|
LOG(ERROR) << "Generating storage key not allowed";
|
|
|
|
return false;
|
|
|
|
}
|
2020-02-12 20:04:05 +01:00
|
|
|
if (gen.use_hw_wrapped_key) {
|
|
|
|
if (gen.keysize != FSCRYPT_MAX_KEY_SIZE) {
|
|
|
|
LOG(ERROR) << "Cannot generate a wrapped key " << gen.keysize << " bytes long";
|
|
|
|
return false;
|
|
|
|
}
|
2021-03-15 20:44:36 +01:00
|
|
|
LOG(DEBUG) << "Generating wrapped storage key";
|
2020-02-03 22:06:45 +01:00
|
|
|
return generateWrappedStorageKey(key);
|
2020-02-12 20:04:05 +01:00
|
|
|
} else {
|
2021-03-15 20:44:36 +01:00
|
|
|
LOG(DEBUG) << "Generating standard storage key";
|
2020-02-12 20:04:05 +01:00
|
|
|
return randomKey(gen.keysize, key);
|
2020-02-03 22:06:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-02 20:01:19 +02:00
|
|
|
// Get raw keyref - used to make keyname and to pass to ioctl
|
2018-10-23 22:07:43 +02:00
|
|
|
static std::string generateKeyRef(const uint8_t* key, int length) {
|
2016-06-02 20:01:19 +02:00
|
|
|
SHA512_CTX c;
|
|
|
|
|
|
|
|
SHA512_Init(&c);
|
|
|
|
SHA512_Update(&c, key, length);
|
|
|
|
unsigned char key_ref1[SHA512_DIGEST_LENGTH];
|
|
|
|
SHA512_Final(key_ref1, &c);
|
|
|
|
|
|
|
|
SHA512_Init(&c);
|
|
|
|
SHA512_Update(&c, key_ref1, SHA512_DIGEST_LENGTH);
|
|
|
|
unsigned char key_ref2[SHA512_DIGEST_LENGTH];
|
|
|
|
SHA512_Final(key_ref2, &c);
|
|
|
|
|
2019-12-17 22:11:25 +01:00
|
|
|
static_assert(FSCRYPT_KEY_DESCRIPTOR_SIZE <= SHA512_DIGEST_LENGTH,
|
|
|
|
"Hash too short for descriptor");
|
|
|
|
return std::string((char*)key_ref2, FSCRYPT_KEY_DESCRIPTOR_SIZE);
|
2016-06-02 20:01:19 +02:00
|
|
|
}
|
|
|
|
|
2019-09-30 22:05:58 +02:00
|
|
|
static std::string keyrefstring(const std::string& raw_ref) {
|
2016-06-02 20:01:19 +02:00
|
|
|
std::ostringstream o;
|
2017-08-18 08:49:45 +02:00
|
|
|
for (unsigned char i : raw_ref) {
|
2016-06-02 20:01:19 +02:00
|
|
|
o << std::hex << std::setw(2) << std::setfill('0') << (int)i;
|
|
|
|
}
|
|
|
|
return o.str();
|
|
|
|
}
|
|
|
|
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
// Build a struct fscrypt_key_specifier for use in the key management ioctls.
|
2020-01-24 00:29:30 +01:00
|
|
|
static bool buildKeySpecifier(fscrypt_key_specifier* spec, const EncryptionPolicy& policy) {
|
|
|
|
switch (policy.options.version) {
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
case 1:
|
2020-01-24 00:29:30 +01:00
|
|
|
if (policy.key_raw_ref.size() != FSCRYPT_KEY_DESCRIPTOR_SIZE) {
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
LOG(ERROR) << "Invalid key specifier size for v1 encryption policy: "
|
2020-01-24 00:29:30 +01:00
|
|
|
<< policy.key_raw_ref.size();
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
spec->type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR;
|
2020-01-24 00:29:30 +01:00
|
|
|
memcpy(spec->u.descriptor, policy.key_raw_ref.c_str(), FSCRYPT_KEY_DESCRIPTOR_SIZE);
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
return true;
|
|
|
|
case 2:
|
2020-01-24 00:29:30 +01:00
|
|
|
if (policy.key_raw_ref.size() != FSCRYPT_KEY_IDENTIFIER_SIZE) {
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
LOG(ERROR) << "Invalid key specifier size for v2 encryption policy: "
|
2020-01-24 00:29:30 +01:00
|
|
|
<< policy.key_raw_ref.size();
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
spec->type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
|
2020-01-24 00:29:30 +01:00
|
|
|
memcpy(spec->u.identifier, policy.key_raw_ref.c_str(), FSCRYPT_KEY_IDENTIFIER_SIZE);
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
return true;
|
|
|
|
default:
|
2020-01-24 00:29:30 +01:00
|
|
|
LOG(ERROR) << "Invalid encryption policy version: " << policy.options.version;
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-24 00:29:30 +01:00
|
|
|
bool installKey(const std::string& mountpoint, const EncryptionOptions& options,
|
|
|
|
const KeyBuffer& key, EncryptionPolicy* policy) {
|
2023-02-22 03:28:28 +01:00
|
|
|
const std::lock_guard<std::mutex> lock(fscrypt_keyring_mutex);
|
2020-01-24 00:29:30 +01:00
|
|
|
policy->options = options;
|
2019-09-30 22:05:58 +02:00
|
|
|
// Put the fscrypt_add_key_arg in an automatically-zeroing buffer, since we
|
|
|
|
// have to copy the raw key into it.
|
|
|
|
KeyBuffer arg_buf(sizeof(struct fscrypt_add_key_arg) + key.size(), 0);
|
|
|
|
struct fscrypt_add_key_arg* arg = (struct fscrypt_add_key_arg*)arg_buf.data();
|
|
|
|
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
// Initialize the "key specifier", which is like a name for the key.
|
2020-01-24 00:29:30 +01:00
|
|
|
switch (options.version) {
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
case 1:
|
|
|
|
// A key for a v1 policy is specified by an arbitrary 8-byte
|
|
|
|
// "descriptor", which must be provided by userspace. We use the
|
|
|
|
// first 8 bytes from the double SHA-512 of the key itself.
|
2020-09-25 16:56:33 +02:00
|
|
|
if (options.use_hw_wrapped_key) {
|
|
|
|
/* When wrapped key is supported, only the first 32 bytes are
|
|
|
|
the same per boot. The second 32 bytes can change as the ephemeral
|
|
|
|
key is different. */
|
|
|
|
policy->key_raw_ref = generateKeyRef((const uint8_t*)key.data(), key.size()/2);
|
|
|
|
} else {
|
|
|
|
policy->key_raw_ref = generateKeyRef((const uint8_t*)key.data(), key.size());
|
|
|
|
}
|
|
|
|
if (!isFsKeyringSupported()) {
|
|
|
|
return installKeyLegacy(key, policy->key_raw_ref);
|
|
|
|
}
|
2020-01-24 00:29:30 +01:00
|
|
|
if (!buildKeySpecifier(&arg->key_spec, *policy)) {
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
// A key for a v2 policy is specified by an 16-byte "identifier",
|
|
|
|
// which is a cryptographic hash of the key itself which the kernel
|
|
|
|
// computes and returns. Any user-provided value is ignored; we
|
|
|
|
// just need to set the specifier type to indicate that we're adding
|
|
|
|
// this type of key.
|
|
|
|
arg->key_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
|
|
|
|
break;
|
|
|
|
default:
|
2020-01-24 00:29:30 +01:00
|
|
|
LOG(ERROR) << "Invalid encryption policy version: " << options.version;
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
return false;
|
|
|
|
}
|
2019-09-30 22:05:58 +02:00
|
|
|
|
2023-08-07 21:35:01 +02:00
|
|
|
if (options.use_hw_wrapped_key) arg->__flags |= __FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED;
|
|
|
|
// Provide the raw key.
|
2019-09-30 22:05:58 +02:00
|
|
|
arg->raw_size = key.size();
|
|
|
|
memcpy(arg->raw, key.data(), key.size());
|
|
|
|
|
2023-08-07 21:35:01 +02:00
|
|
|
android::base::unique_fd fd(open(mountpoint.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
|
|
|
|
if (fd == -1) {
|
|
|
|
PLOG(ERROR) << "Failed to open " << mountpoint << " to install key";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ioctl(fd, FS_IOC_ADD_ENCRYPTION_KEY, arg) != 0) {
|
|
|
|
PLOG(ERROR) << "Failed to install fscrypt key to " << mountpoint;
|
|
|
|
return false;
|
|
|
|
}
|
2019-09-30 22:05:58 +02:00
|
|
|
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
if (arg->key_spec.type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
|
|
|
|
// Retrieve the key identifier that the kernel computed.
|
2020-01-24 00:29:30 +01:00
|
|
|
policy->key_raw_ref =
|
|
|
|
std::string((char*)arg->key_spec.u.identifier, FSCRYPT_KEY_IDENTIFIER_SIZE);
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
}
|
2023-08-07 21:35:01 +02:00
|
|
|
LOG(DEBUG) << "Installed fscrypt key with ref " << keyrefstring(policy->key_raw_ref) << " to "
|
|
|
|
<< mountpoint;
|
2019-09-30 22:05:58 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-02-22 03:28:28 +01:00
|
|
|
static void waitForBusyFiles(const struct fscrypt_key_specifier key_spec, const std::string ref,
|
|
|
|
const std::string mountpoint) {
|
|
|
|
android::base::unique_fd fd(open(mountpoint.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
|
|
|
|
if (fd == -1) {
|
|
|
|
PLOG(ERROR) << "Failed to open " << mountpoint << " to evict key";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::chrono::milliseconds wait_time(3200);
|
|
|
|
std::chrono::milliseconds total_wait_time(0);
|
|
|
|
while (wait_time <= std::chrono::milliseconds(51200)) {
|
|
|
|
total_wait_time += wait_time;
|
|
|
|
std::this_thread::sleep_for(wait_time);
|
|
|
|
|
|
|
|
const std::lock_guard<std::mutex> lock(fscrypt_keyring_mutex);
|
|
|
|
|
|
|
|
struct fscrypt_get_key_status_arg get_arg;
|
|
|
|
memset(&get_arg, 0, sizeof(get_arg));
|
|
|
|
get_arg.key_spec = key_spec;
|
|
|
|
|
|
|
|
if (ioctl(fd, FS_IOC_GET_ENCRYPTION_KEY_STATUS, &get_arg) != 0) {
|
|
|
|
PLOG(ERROR) << "Failed to get status for fscrypt key with ref " << ref << " from "
|
|
|
|
<< mountpoint;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (get_arg.status != FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED) {
|
|
|
|
LOG(DEBUG) << "Key status changed, cancelling busy file cleanup for key with ref "
|
|
|
|
<< ref << ".";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct fscrypt_remove_key_arg remove_arg;
|
|
|
|
memset(&remove_arg, 0, sizeof(remove_arg));
|
|
|
|
remove_arg.key_spec = key_spec;
|
|
|
|
|
|
|
|
if (ioctl(fd, FS_IOC_REMOVE_ENCRYPTION_KEY, &remove_arg) != 0) {
|
|
|
|
PLOG(ERROR) << "Failed to clean up busy files for fscrypt key with ref " << ref
|
|
|
|
<< " from " << mountpoint;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (remove_arg.removal_status_flags & FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS) {
|
|
|
|
// Should never happen because keys are only added/removed as root.
|
|
|
|
LOG(ERROR) << "Unexpected case: key with ref " << ref
|
|
|
|
<< " is still added by other users!";
|
|
|
|
} else if (!(remove_arg.removal_status_flags &
|
|
|
|
FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY)) {
|
|
|
|
LOG(INFO) << "Successfully cleaned up busy files for key with ref " << ref
|
|
|
|
<< ". After waiting " << total_wait_time.count() << "ms.";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
LOG(WARNING) << "Files still open after waiting " << total_wait_time.count()
|
|
|
|
<< "ms. Key with ref " << ref << " still has unlocked files!";
|
|
|
|
wait_time *= 2;
|
|
|
|
}
|
|
|
|
LOG(ERROR) << "Waiting for files to close never completed. Files using key with ref " << ref
|
|
|
|
<< " were not locked!";
|
|
|
|
}
|
|
|
|
|
2020-01-24 00:29:30 +01:00
|
|
|
bool evictKey(const std::string& mountpoint, const EncryptionPolicy& policy) {
|
2023-02-22 03:28:28 +01:00
|
|
|
const std::lock_guard<std::mutex> lock(fscrypt_keyring_mutex);
|
2019-09-30 22:05:58 +02:00
|
|
|
|
|
|
|
android::base::unique_fd fd(open(mountpoint.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
|
|
|
|
if (fd == -1) {
|
|
|
|
PLOG(ERROR) << "Failed to open " << mountpoint << " to evict key";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct fscrypt_remove_key_arg arg;
|
|
|
|
memset(&arg, 0, sizeof(arg));
|
|
|
|
|
2020-01-24 00:29:30 +01:00
|
|
|
if (!buildKeySpecifier(&arg.key_spec, policy)) {
|
vold: support v2 encryption policies
Add support for setting v2 encryption policies when configured in the
fstab (for internal storage) or in system properties (for adoptable
storage), and for installing and evicting the keys for such policies.
v2 policies support the same encryption modes and flags as v1 policies,
but internally they use a more standard, secure, and flexible KDF. Due
to this, some future features will be supported by v2 policies only.
Bug: 140500999
Test: Configured a device to use v2 encryption policies (applied the
needed kernel patches and added
"fileencryption=aes-256-xts:aes-256-cts:v2" to fstab, and set the
corresponding system properties for adoptable storage). Wiped
userdata, booted device and checked logs to verify that v2
policies were being used.
Also enabled virtual SD card and formatted as adoptable storage;
verified it works and that v2 policies were being used on it.
Also created, started, and stopped a 2nd user and verified their
keys were evicted.
Also verified that the device comes up again after rebooting.
Also verified that a device using v1 encryption policies continues
to work, both with and without an updated kernel -- including
stopping a user so that their keys get evicted.
Change-Id: If64028d8580584b2c33c614cabd5d6b93657f608
2019-09-30 22:06:47 +02:00
|
|
|
return false;
|
|
|
|
}
|
2019-09-30 22:05:58 +02:00
|
|
|
|
2020-01-24 00:29:30 +01:00
|
|
|
std::string ref = keyrefstring(policy.key_raw_ref);
|
2019-09-30 22:05:58 +02:00
|
|
|
|
|
|
|
if (ioctl(fd, FS_IOC_REMOVE_ENCRYPTION_KEY, &arg) != 0) {
|
|
|
|
PLOG(ERROR) << "Failed to evict fscrypt key with ref " << ref << " from " << mountpoint;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOG(DEBUG) << "Evicted fscrypt key with ref " << ref << " from " << mountpoint;
|
|
|
|
if (arg.removal_status_flags & FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS) {
|
|
|
|
// Should never happen because keys are only added/removed as root.
|
|
|
|
LOG(ERROR) << "Unexpected case: key with ref " << ref << " is still added by other users!";
|
|
|
|
} else if (arg.removal_status_flags & FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY) {
|
2023-02-22 03:28:28 +01:00
|
|
|
LOG(WARNING)
|
|
|
|
<< "Files still open after removing key with ref " << ref
|
|
|
|
<< ". These files were not locked! Punting busy file clean up to worker thread.";
|
|
|
|
// Processes are killed asynchronously in ActivityManagerService due to performance issues
|
|
|
|
// with synchronous kills. If there were busy files they will probably be killed soon. Wait
|
|
|
|
// for them asynchronously.
|
|
|
|
std::thread busyFilesThread(waitForBusyFiles, arg.key_spec, ref, mountpoint);
|
|
|
|
busyFilesThread.detach();
|
2019-09-30 22:05:58 +02:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-02-12 20:04:05 +01:00
|
|
|
bool retrieveOrGenerateKey(const std::string& key_path, const std::string& tmp_path,
|
|
|
|
const KeyAuthentication& key_authentication, const KeyGeneration& gen,
|
2020-11-06 04:58:26 +01:00
|
|
|
KeyBuffer* key) {
|
2016-06-02 20:01:19 +02:00
|
|
|
if (pathExists(key_path)) {
|
|
|
|
LOG(DEBUG) << "Key exists, using: " << key_path;
|
2020-11-06 04:58:26 +01:00
|
|
|
if (!retrieveKey(key_path, key_authentication, key)) return false;
|
2016-06-02 20:04:27 +02:00
|
|
|
} else {
|
2020-02-12 20:04:05 +01:00
|
|
|
if (!gen.allow_gen) {
|
2018-09-18 22:30:21 +02:00
|
|
|
LOG(ERROR) << "No key found in " << key_path;
|
|
|
|
return false;
|
2016-06-02 20:04:27 +02:00
|
|
|
}
|
|
|
|
LOG(INFO) << "Creating new key in " << key_path;
|
2020-02-12 20:04:05 +01:00
|
|
|
if (!generateStorageKey(gen, key)) return false;
|
2020-01-24 00:29:30 +01:00
|
|
|
if (!storeKeyAtomically(key_path, tmp_path, key_authentication, *key)) return false;
|
2016-06-02 20:04:27 +02:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-06-02 20:01:19 +02:00
|
|
|
} // namespace vold
|
|
|
|
} // namespace android
|