blob: 6cf82af438fd88dc81b2bdf07a8900bd3994961a [file] [log] [blame] [edit]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIBHWSEC_BACKEND_TPM2_KEY_MANAGEMENT_H_
#define LIBHWSEC_BACKEND_TPM2_KEY_MANAGEMENT_H_
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <utility>
#include <absl/container/flat_hash_map.h>
#include <absl/container/flat_hash_set.h>
#include <base/timer/timer.h>
#include <brillo/secure_blob.h>
#include <trunks/tpm_generated.h>
#include "libhwsec/backend/key_management.h"
#include "libhwsec/backend/tpm2/config.h"
#include "libhwsec/backend/tpm2/trunks_context.h"
#include "libhwsec/proxy/proxy.h"
#include "libhwsec/status.h"
#include "libhwsec/structures/key.h"
#include "libhwsec/structures/no_default_init.h"
#include "libhwsec/structures/operation_policy.h"
namespace hwsec {
struct KeyReloadDataTpm2 {
brillo::Blob key_blob;
uint32_t client_count;
base::TimeDelta lazy_expiration_time;
std::unique_ptr<base::OneShotTimer> flush_timer;
};
struct KeyTpm2 {
enum class Type {
kPersistentKey,
kTransientKey,
kReloadableTransientKey,
};
struct Cache {
OperationPolicy policy;
NoDefault<trunks::TPMT_PUBLIC> public_area;
};
NoDefault<Type> type;
NoDefault<trunks::TPM_HANDLE> key_handle;
NoDefault<Cache> cache;
std::optional<KeyReloadDataTpm2> reload_data;
};
class KeyManagementTpm2 : public KeyManagement {
public:
KeyManagementTpm2(TrunksContext& context,
ConfigTpm2& config,
org::chromium::TpmManagerProxyInterface& tpm_manager,
MiddlewareDerivative& middleware_derivative)
: context_(context),
config_(config),
tpm_manager_(tpm_manager),
middleware_derivative_(middleware_derivative) {}
~KeyManagementTpm2();
StatusOr<absl::flat_hash_set<KeyAlgoType>> GetSupportedAlgo() override;
Status IsSupported(KeyAlgoType key_algo,
const CreateKeyOptions& options) override;
StatusOr<CreateKeyResult> CreateKey(const OperationPolicySetting& policy,
KeyAlgoType key_algo,
const LoadKeyOptions& load_key_options,
const CreateKeyOptions& options) override;
StatusOr<ScopedKey> LoadKey(const OperationPolicy& policy,
const brillo::Blob& key_blob,
const LoadKeyOptions& load_key_options) override;
StatusOr<ScopedKey> GetPolicyEndorsementKey(
const OperationPolicySetting& policy, KeyAlgoType key_algo) override;
StatusOr<ScopedKey> GetPersistentKey(PersistentKeyType key_type) override;
StatusOr<brillo::Blob> GetPubkeyHash(Key key) override;
Status Flush(Key key) override;
Status ReloadIfPossible(Key key) override;
StatusOr<ScopedKey> SideLoadKey(uint32_t key_handle) override;
StatusOr<uint32_t> GetKeyHandle(Key key) override;
StatusOr<CreateKeyResult> WrapRSAKey(
const OperationPolicySetting& policy,
const brillo::Blob& public_modulus,
const brillo::SecureBlob& private_prime_factor,
const LoadKeyOptions& load_key_options,
const CreateKeyOptions& options) override;
StatusOr<CreateKeyResult> WrapECCKey(
const OperationPolicySetting& policy,
const brillo::Blob& public_point_x,
const brillo::Blob& public_point_y,
const brillo::SecureBlob& private_value,
const LoadKeyOptions& load_key_options,
const CreateKeyOptions& options) override;
StatusOr<RSAPublicInfo> GetRSAPublicInfo(Key key) override;
StatusOr<ECCPublicInfo> GetECCPublicInfo(Key key) override;
// Below are TPM2.0 specific code.
// Gets the reference of the internal key data.
StatusOr<std::reference_wrapper<KeyTpm2>> GetKeyData(Key key);
// Loads the key from its DER-encoded Subject Public Key Info. Algorithm
// scheme and hashing algorithm are passed via |scheme| and |hash_alg|.
// Currently, only the RSA signing keys are supported.
StatusOr<ScopedKey> LoadPublicKeyFromSpki(
const brillo::Blob& public_key_spki_der,
trunks::TPM_ALG_ID scheme,
trunks::TPM_ALG_ID hash_alg);
private:
StatusOr<CreateKeyResult> CreateRsaKey(
const OperationPolicySetting& policy,
const CreateKeyOptions& options,
const LoadKeyOptions& load_key_options);
StatusOr<CreateKeyResult> CreateSoftwareGenRsaKey(
const OperationPolicySetting& policy,
const CreateKeyOptions& options,
const LoadKeyOptions& load_key_options);
StatusOr<CreateKeyResult> CreateEccKey(
const OperationPolicySetting& policy,
const CreateKeyOptions& options,
const LoadKeyOptions& load_key_options);
StatusOr<ScopedKey> LoadKeyInternal(
const OperationPolicy& policy,
KeyTpm2::Type key_type,
uint32_t key_handle,
std::optional<KeyReloadDataTpm2> reload_data);
Status FlushTransientKey(Key key, KeyTpm2& key_data);
Status FlushKeyTokenAndHandle(KeyToken token, trunks::TPM_HANDLE handle);
TrunksContext& context_;
ConfigTpm2& config_;
org::chromium::TpmManagerProxyInterface& tpm_manager_;
MiddlewareDerivative& middleware_derivative_;
KeyToken current_token_ = 0;
absl::flat_hash_map<KeyToken, KeyTpm2> key_map_;
absl::flat_hash_map<PersistentKeyType, KeyToken> persistent_key_map_;
bool shall_flush_immediately_ = false;
};
} // namespace hwsec
#endif // LIBHWSEC_BACKEND_TPM2_KEY_MANAGEMENT_H_