Merge "Add support for binding storage encryption to a seed"

This commit is contained in:
Seth Moore 2021-01-27 00:40:35 +00:00 committed by Gerrit Code Review
commit 6207c9cde4
5 changed files with 75 additions and 0 deletions

View file

@ -22,6 +22,8 @@
#include "Utils.h"
#include <algorithm>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>
@ -82,6 +84,31 @@ static const char* kFn_secdiscardable = "secdiscardable";
static const char* kFn_stretching = "stretching";
static const char* kFn_version = "version";
namespace {
// Storage binding info for ensuring key encryption keys include a
// platform-provided seed in their derivation.
struct StorageBindingInfo {
enum class State {
UNINITIALIZED,
IN_USE, // key storage keys are bound to seed
NOT_USED, // key storage keys are NOT bound to seed
};
// Binding seed mixed into all key storage keys.
std::vector<uint8_t> seed;
// State tracker for the key storage key binding.
State state = State::UNINITIALIZED;
std::mutex guard;
};
// Never freed as the dtor is non-trivial.
StorageBindingInfo& storage_binding_info = *new StorageBindingInfo;
} // namespace
static bool checkSize(const std::string& kind, size_t actual, size_t expected) {
if (actual != expected) {
LOG(ERROR) << "Wrong number of bytes in " << kind << ", expected " << expected << " got "
@ -456,6 +483,20 @@ static bool generateAppId(const KeyAuthentication& auth, const std::string& stre
std::string stretched;
if (!stretchSecret(stretching, auth.secret, salt, &stretched)) return false;
*appId = secdiscardable_hash + stretched;
const std::lock_guard<std::mutex> scope_lock(storage_binding_info.guard);
switch (storage_binding_info.state) {
case StorageBindingInfo::State::UNINITIALIZED:
storage_binding_info.state = StorageBindingInfo::State::NOT_USED;
break;
case StorageBindingInfo::State::IN_USE:
appId->append(storage_binding_info.seed.begin(), storage_binding_info.seed.end());
break;
case StorageBindingInfo::State::NOT_USED:
// noop
break;
}
return true;
}
@ -715,5 +756,22 @@ bool destroyKey(const std::string& dir) {
return success;
}
bool setKeyStorageBindingSeed(const std::vector<uint8_t>& seed) {
const std::lock_guard<std::mutex> scope_lock(storage_binding_info.guard);
switch (storage_binding_info.state) {
case StorageBindingInfo::State::UNINITIALIZED:
storage_binding_info.state = StorageBindingInfo::State::IN_USE;
storage_binding_info.seed = seed;
return true;
case StorageBindingInfo::State::IN_USE:
LOG(ERROR) << "key storage binding seed already set";
return false;
case StorageBindingInfo::State::NOT_USED:
LOG(ERROR) << "key storage already in use without binding";
return false;
}
return false;
}
} // namespace vold
} // namespace android

View file

@ -19,7 +19,9 @@
#include "KeyBuffer.h"
#include <cstdint>
#include <string>
#include <vector>
namespace android {
namespace vold {
@ -72,6 +74,9 @@ bool runSecdiscardSingle(const std::string& file);
bool generateWrappedStorageKey(KeyBuffer* key);
// Export the per-boot boot wrapped storage key using keymaster.
bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key);
// Set a seed to be mixed into all key storage encryption keys.
bool setKeyStorageBindingSeed(const std::vector<uint8_t>& seed);
} // namespace vold
} // namespace android

View file

@ -33,6 +33,7 @@
#include "Checkpoint.h"
#include "FsCrypt.h"
#include "IdleMaint.h"
#include "KeyStorage.h"
#include "Keymaster.h"
#include "MetadataCrypt.h"
#include "MoveStorage.h"
@ -699,6 +700,13 @@ binder::Status VoldNativeService::encryptFstab(const std::string& blkDevice,
fscrypt_mount_metadata_encrypted(blkDevice, mountPoint, true, shouldFormat, fsType));
}
binder::Status VoldNativeService::setStorageBindingSeed(const std::vector<uint8_t>& seed) {
ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_CRYPT_LOCK;
return translateBool(setKeyStorageBindingSeed(seed));
}
binder::Status VoldNativeService::createUserKey(int32_t userId, int32_t userSerial,
bool ephemeral) {
ENFORCE_SYSTEM_OR_ROOT;

View file

@ -116,6 +116,8 @@ class VoldNativeService : public BinderService<VoldNativeService>, public os::Bn
binder::Status encryptFstab(const std::string& blkDevice, const std::string& mountPoint,
bool shouldFormat, const std::string& fsType);
binder::Status setStorageBindingSeed(const std::vector<uint8_t>& seed);
binder::Status createUserKey(int32_t userId, int32_t userSerial, bool ephemeral);
binder::Status destroyUserKey(int32_t userId);

View file

@ -91,6 +91,8 @@ interface IVold {
void mountFstab(@utf8InCpp String blkDevice, @utf8InCpp String mountPoint);
void encryptFstab(@utf8InCpp String blkDevice, @utf8InCpp String mountPoint, boolean shouldFormat, @utf8InCpp String fsType);
void setStorageBindingSeed(in byte[] seed);
void createUserKey(int userId, int userSerial, boolean ephemeral);
void destroyUserKey(int userId);