blob: 7a82af88ddff1aa89de6cc5bf26ea38a62b0f9a9 [file] [log] [blame]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cryptohome/storage/cryptohome_vault_factory.h"
#include <memory>
#include <string>
#include <utility>
#include <base/files/file_path.h>
#include "cryptohome/filesystem_layout.h"
#include "cryptohome/platform.h"
#include "cryptohome/storage/cryptohome_vault.h"
#include "cryptohome/storage/encrypted_container/encrypted_container.h"
#include "cryptohome/storage/encrypted_container/encrypted_container_factory.h"
#include "cryptohome/storage/encrypted_container/filesystem_key.h"
namespace {
// Size of logical volumes to use for the dm-crypt cryptohomes.
constexpr uint64_t kLogicalVolumeSizePercent = 90;
} // namespace
namespace cryptohome {
CryptohomeVaultFactory::CryptohomeVaultFactory(
Platform* platform,
std::unique_ptr<EncryptedContainerFactory> encrypted_container_factory)
: platform_(platform),
encrypted_container_factory_(std::move(encrypted_container_factory)) {}
CryptohomeVaultFactory::CryptohomeVaultFactory(Platform* platform)
: CryptohomeVaultFactory(
platform, std::make_unique<EncryptedContainerFactory>(platform)) {}
CryptohomeVaultFactory::~CryptohomeVaultFactory() {}
std::unique_ptr<EncryptedContainer>
CryptohomeVaultFactory::GenerateEncryptedContainer(
EncryptedContainerType type,
const std::string& obfuscated_username,
const FileSystemKeyReference& key_reference,
const std::string& container_identifier) {
EncryptedContainerConfig config;
base::FilePath stateful_device;
uint64_t stateful_size;
switch (type) {
case EncryptedContainerType::kEcryptfs:
config.backing_dir = GetEcryptfsUserVaultPath(obfuscated_username);
config.type = EncryptedContainerType::kEcryptfs;
break;
case EncryptedContainerType::kFscrypt:
config.backing_dir = GetUserMountDirectory(obfuscated_username);
config.type = EncryptedContainerType::kFscrypt;
break;
case EncryptedContainerType::kDmcrypt:
// Calculate size for dm-crypt partition.
stateful_device = platform_->GetStatefulDevice();
if (stateful_device.empty())
return nullptr;
if (!platform_->GetBlkSize(stateful_device, &stateful_size))
return nullptr;
config.type = EncryptedContainerType::kDmcrypt;
config.dmcrypt_config = {
.backing_device_config =
{.type = BackingDeviceType::kLogicalVolumeBackingDevice,
.name = LogicalVolumePrefix(obfuscated_username) +
container_identifier,
.size = static_cast<int64_t>(
(stateful_size * kLogicalVolumeSizePercent) /
(100 * 1024 * 1024)),
.logical_volume = {.thinpool_name = "thinpool",
.physical_volume = stateful_device}},
.dmcrypt_device_name =
DmcryptVolumePrefix(obfuscated_username) + container_identifier,
.dmcrypt_cipher = "aes-xts-plain64",
// TODO(sarthakkukreti): Add more dynamic checks for filesystem
// features once dm-crypt cryptohomes are stable.
.mkfs_opts = {"-O", "^huge_file,^flex_bg,", "-E",
"discard,lazy_itable_init"},
.tune2fs_opts = {"-O", "verity,quota", "-Q", "usrquota,grpquota"}};
break;
default:
return nullptr;
}
return encrypted_container_factory_->Generate(config, key_reference);
}
std::unique_ptr<CryptohomeVault> CryptohomeVaultFactory::Generate(
const std::string& obfuscated_username,
const FileSystemKeyReference& key_reference,
EncryptedContainerType container_type,
EncryptedContainerType migrating_container_type) {
// Generate containers for the vault.
std::unique_ptr<EncryptedContainer> container =
GenerateEncryptedContainer(container_type, obfuscated_username,
key_reference, kDmcryptDataContainerSuffix);
std::unique_ptr<EncryptedContainer> migrating_container =
GenerateEncryptedContainer(migrating_container_type, obfuscated_username,
key_reference, kDmcryptDataContainerSuffix);
std::unique_ptr<EncryptedContainer> cache_container;
if (container_type == EncryptedContainerType::kDmcrypt) {
cache_container =
GenerateEncryptedContainer(container_type, obfuscated_username,
key_reference, kDmcryptCacheContainerSuffix);
}
return std::make_unique<CryptohomeVault>(
obfuscated_username, std::move(container), std::move(migrating_container),
std::move(cache_container), platform_);
}
} // namespace cryptohome