Skip to content

Commit

Permalink
vold: Import FBE wrappedkey changes from CAF
Browse files Browse the repository at this point in the history
  • Loading branch information
adithya2306 committed Oct 17, 2021
1 parent 0b6de6c commit a15b8a4
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 11 deletions.
16 changes: 13 additions & 3 deletions FsCrypt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "FsCrypt.h"

#include "Keymaster.h"
#include "KeyStorage.h"
#include "KeyUtil.h"
#include "Utils.h"
Expand Down Expand Up @@ -249,6 +250,10 @@ static bool get_data_file_encryption_options(EncryptionOptions* options) {
"this flag from the device's fstab";
return false;
}
if (options->version == 1) {
options->use_hw_wrapped_key =
GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT)->fs_mgr_flags.wrapped_key;
}
return true;
}

Expand Down Expand Up @@ -289,6 +294,10 @@ static bool get_volume_file_encryption_options(EncryptionOptions* options) {
return true;
}

bool is_metadata_wrapped_key_supported() {
return GetEntryForMountPoint(&fstab_default, METADATA_MNT_POINT)->fs_mgr_flags.wrapped_key;
}

static bool read_and_install_user_ce_key(userid_t user_id,
const android::vold::KeyAuthentication& auth) {
if (s_ce_policies.count(user_id) != 0) return true;
Expand Down Expand Up @@ -644,7 +653,7 @@ static std::string volume_secdiscardable_path(const std::string& volume_uuid) {
}

static bool read_or_create_volkey(const std::string& misc_path, const std::string& volume_uuid,
EncryptionPolicy* policy) {
EncryptionPolicy* policy, int flags) {
auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
std::string secdiscardable_hash;
if (android::vold::pathExists(secdiscardable_path)) {
Expand Down Expand Up @@ -693,6 +702,7 @@ static bool fscrypt_rewrap_user_key(userid_t user_id, int serial,
return false;
}
auto const paths = get_ce_key_paths(directory_path);

std::string ce_key_path;
if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, store_auth, ce_key))
Expand Down Expand Up @@ -837,7 +847,7 @@ bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_
if (!EnsurePolicy(de_policy, misc_de_path)) return false;
if (!EnsurePolicy(de_policy, vendor_de_path)) return false;
} else {
if (!read_or_create_volkey(misc_de_path, volume_uuid, &de_policy)) return false;
if (!read_or_create_volkey(misc_de_path, volume_uuid, &de_policy, flags)) return false;
}
if (!EnsurePolicy(de_policy, user_de_path)) return false;
}
Expand Down Expand Up @@ -876,7 +886,7 @@ bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_
if (!EnsurePolicy(ce_policy, misc_ce_path)) return false;
if (!EnsurePolicy(ce_policy, vendor_ce_path)) return false;
} else {
if (!read_or_create_volkey(misc_ce_path, volume_uuid, &ce_policy)) return false;
if (!read_or_create_volkey(misc_ce_path, volume_uuid, &ce_policy, flags)) return false;
}
if (!EnsurePolicy(ce_policy, media_ce_path)) return false;
if (!EnsurePolicy(ce_policy, user_ce_path)) return false;
Expand Down
1 change: 1 addition & 0 deletions FsCrypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_
bool fscrypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags);

bool fscrypt_destroy_volume_keys(const std::string& volume_uuid);
bool is_metadata_wrapped_key_supported();
32 changes: 29 additions & 3 deletions KeyStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ static constexpr size_t AES_KEY_BYTES = 32;
static constexpr size_t GCM_NONCE_BYTES = 12;
static constexpr size_t GCM_MAC_BYTES = 16;
static constexpr size_t SECDISCARDABLE_BYTES = 1 << 14;
constexpr int EXT4_AES_256_XTS_KEY_SIZE = 64;

static const char* kCurrentVersion = "1";
static const char* kRmPath = "/system/bin/rm";
Expand All @@ -74,6 +75,8 @@ static const char* kFn_secdiscardable = "secdiscardable";
static const char* kFn_stretching = "stretching";
static const char* kFn_version = "version";

static const int32_t KM_TAG_FBE_ICE = static_cast<int32_t>(7 << 28) | 16201;

namespace {

// Storage binding info for ensuring key encryption keys include a
Expand Down Expand Up @@ -154,8 +157,14 @@ bool generateWrappedStorageKey(KeyBuffer* key) {
Keymaster keymaster;
if (!keymaster) return false;
std::string key_temp;
auto paramBuilder = km::AuthorizationSetBuilder().AesEncryptionKey(AES_KEY_BYTES * 8);
paramBuilder.Authorization(km::TAG_STORAGE_KEY);
auto paramBuilder = km::AuthorizationSetBuilder().AesEncryptionKey(AES_KEY_BYTES * 8)
.Authorization(km::TAG_STORAGE_KEY);

km::KeyParameter param1;
param1.tag = (km::Tag) (KM_TAG_FBE_ICE);
param1.value = km::KeyParameterValue::make<km::KeyParameterValue::boolValue>(true);
paramBuilder.push_back(param1);

if (!generateKeymasterKey(keymaster, paramBuilder, &key_temp)) return false;
*key = KeyBuffer(key_temp.size());
memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
Expand All @@ -167,7 +176,24 @@ bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key) {
if (!keymaster) return false;
std::string key_temp;

if (!keymaster.exportKey(kmKey, &key_temp)) return false;
auto ret = keymaster.exportKey(kmKey, &key_temp);
if (ret != km::ErrorCode::OK) {
if (ret == km::ErrorCode::KEY_REQUIRES_UPGRADE) {
// TODO(b/187304488): Re-land the below logic. (keymaster.upgradeKey() was removed)
return false;
/*
std::string kmKeyStr(reinterpret_cast<const char*>(kmKey.data()), kmKey.size());
std::string Keystr;
if (!keymaster.upgradeKey(kmKeyStr, km::AuthorizationSet(), &Keystr)) return false;
KeyBuffer upgradedKey = KeyBuffer(Keystr.size());
memcpy(reinterpret_cast<void*>(upgradedKey.data()), Keystr.c_str(), upgradedKey.size());
ret = keymaster.exportKey(upgradedKey, &key_temp);
if (ret != km::ErrorCode::OK) return false;
*/
} else {
return false;
}
}
*key = KeyBuffer(key_temp.size());
memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
return true;
Expand Down
7 changes: 7 additions & 0 deletions KeyStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ class KeyAuthentication {
const std::string secret;
};

enum class KeyType {
DE_SYS,
DE_USER,
CE_USER,
ME,
};

extern const KeyAuthentication kEmptyAuthentication;

bool createSecdiscardable(const std::string& path, std::string* hash);
Expand Down
9 changes: 8 additions & 1 deletion KeyUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,14 @@ bool installKey(const std::string& mountpoint, const EncryptionOptions& options,
// 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.
policy->key_raw_ref = generateKeyRef((const uint8_t*)key.data(), key.size());
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);
}
Expand Down
6 changes: 3 additions & 3 deletions Keymaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ bool Keymaster::generateKey(const km::AuthorizationSet& inParams, std::string* k
return true;
}

bool Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) {
bool ret = false;
km::ErrorCode Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) {
km::ErrorCode ret = km::ErrorCode::UNKNOWN_ERROR;
ks2::KeyDescriptor storageKey = {
.domain = ks2::Domain::BLOB,
.alias = std::nullopt,
Expand All @@ -168,7 +168,7 @@ bool Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) {

// TODO b/185811713 store the upgraded key blob if provided and delete the old key blob.

ret = true;
ret = km::ErrorCode::OK;
out:
zeroize_vector(ephemeral_key_response.ephemeralKey);
zeroize_vector(storageKey.blob.value());
Expand Down
2 changes: 1 addition & 1 deletion Keymaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class Keymaster {
// Generate a key using keystore2 from the given params.
bool generateKey(const km::AuthorizationSet& inParams, std::string* key);
// Exports a keystore2 key with STORAGE_KEY tag wrapped with a per-boot ephemeral key
bool exportKey(const KeyBuffer& kmKey, std::string* key);
km::ErrorCode exportKey(const KeyBuffer& kmKey, std::string* key);
// If supported, permanently delete a key from the keymint device it belongs to.
bool deleteKey(const std::string& key);
// Begin a new cryptographic operation, collecting output parameters if pointer is non-null
Expand Down
3 changes: 3 additions & 0 deletions MetadataCrypt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "Checkpoint.h"
#include "CryptoType.h"
#include "EncryptInplace.h"
#include "FsCrypt.h"
#include "KeyStorage.h"
#include "KeyUtil.h"
#include "Keymaster.h"
Expand Down Expand Up @@ -241,6 +242,8 @@ bool fscrypt_mount_metadata_encrypted(const std::string& blk_device, const std::
}
options.cipher = legacy_aes_256_xts;
options.use_legacy_options_format = true;
if (is_metadata_wrapped_key_supported())
options.use_hw_wrapped_key = true;
options.set_dun = android::base::GetBoolProperty("ro.crypto.set_dun", false);
if (!options.set_dun && data_rec->fs_mgr_flags.checkpoint_blk) {
LOG(ERROR)
Expand Down
1 change: 1 addition & 0 deletions VoldUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
extern android::fs_mgr::Fstab fstab_default;

#define DATA_MNT_POINT "/data"
#define METADATA_MNT_POINT "/metadata"

0 comments on commit a15b8a4

Please sign in to comment.