blob: 88cdcedb8952edccd138f5a8dd15acd8e9e79dd7 [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_TPM1_KEY_MANAGEMENT_H_
#define LIBHWSEC_BACKEND_TPM1_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 <brillo/secure_blob.h>
#include "libhwsec/backend/key_management.h"
#include "libhwsec/backend/tpm1/config.h"
#include "libhwsec/backend/tpm1/tss_helper.h"
#include "libhwsec/middleware/middleware_derivative.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"
#include "libhwsec/tss_utils/scoped_tss_type.h"
namespace hwsec {
struct KeyReloadDataTpm1 {
OperationPolicy policy;
brillo::Blob key_blob;
};
struct KeyTpm1 {
enum class Type {
kPersistentKey,
kTransientKey,
kReloadableTransientKey,
};
struct Cache {
brillo::Blob pubkey_blob;
};
NoDefault<Type> type;
NoDefault<TSS_HKEY> key_handle;
NoDefault<Cache> cache;
std::optional<ScopedTssKey> scoped_key;
std::optional<ScopedTssPolicy> scoped_policy;
std::optional<KeyReloadDataTpm1> reload_data;
};
class KeyManagementTpm1 : public KeyManagement {
public:
KeyManagementTpm1(overalls::Overalls& overalls,
TssHelper& tss_helper,
ConfigTpm1& config,
MiddlewareDerivative& middleware_derivative)
: overalls_(overalls),
tss_helper_(tss_helper),
config_(config),
middleware_derivative_(middleware_derivative) {}
~KeyManagementTpm1();
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 TPM1.2 specific code.
// Gets the reference of the internal key data.
StatusOr<std::reference_wrapper<KeyTpm1>> GetKeyData(Key key);
// Creates a key object for the RSA public key, given its public modulus in
// |key_modulus|, creation flags in |key_flags|, signature scheme or
// |TSS_SS_NONE| in |signature_scheme|, encryption scheme or |TSS_ES_NONE|
// in |encryption_scheme|. The key's public exponent is assumed to be 65537.
StatusOr<ScopedKey> CreateRsaPublicKeyObject(brillo::Blob key_modulus,
uint32_t key_flags,
uint32_t signature_scheme,
uint32_t encryption_scheme);
// Loads the key from its DER-encoded Subject Public Key Info.
// Currently, only the RSA signing keys are supported.
StatusOr<ScopedKey> LoadPublicKeyFromSpki(
const brillo::Blob& public_key_spki_der,
uint32_t signature_scheme,
uint32_t encryption_scheme);
private:
struct KeyPolicyPair {
ScopedTssKey tss_key;
ScopedTssPolicy tss_policy;
};
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<KeyPolicyPair> LoadKeyBlob(const OperationPolicy& policy,
const brillo::Blob& key_blob);
StatusOr<ScopedKey> LoadKeyInternal(
KeyTpm1::Type key_type,
uint32_t key_handle,
std::optional<KeyPolicyPair> key_policy_pair,
std::optional<KeyReloadDataTpm1> reload_data);
StatusOr<brillo::Blob> GetPubkeyBlob(uint32_t key_handle);
StatusOr<uint32_t> GetSrk();
overalls::Overalls& overalls_;
TssHelper& tss_helper_;
ConfigTpm1& config_;
MiddlewareDerivative& middleware_derivative_;
KeyToken current_token_ = 0;
absl::flat_hash_map<KeyToken, KeyTpm1> key_map_;
absl::flat_hash_map<PersistentKeyType, KeyToken> persistent_key_map_;
std::optional<ScopedTssKey> srk_cache_;
};
} // namespace hwsec
#endif // LIBHWSEC_BACKEND_TPM1_KEY_MANAGEMENT_H_