Merge "Add support for binding storage encryption to a seed" am: 6207c9cde4
am: 4c110af013
Original change: https://android-review.googlesource.com/c/platform/system/vold/+/1553317 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Ib2d7a8c3538ab8c43e1fe4d783bf2b5d83c826ca
This commit is contained in:
commit
0bdfada404
5 changed files with 75 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue