9#include <botan/tpm2_ecc.h>
11#include <botan/internal/stl_util.h>
12#include <botan/internal/tpm2_algo_mappings.h>
13#include <botan/internal/tpm2_hash.h>
14#include <botan/internal/tpm2_pkops.h>
15#include <botan/internal/tpm2_util.h>
17#include <tss2/tss2_esys.h>
22 EC_PublicKey(std::move(handle), std::move(sessions), ecc_pubkey_from_tss2_public(public_blob)) {}
30 const TPM2B_PUBLIC* public_blob,
31 std::span<const uint8_t> private_blob) :
32 EC_PrivateKey(std::move(handle), std::move(sessions), ecc_pubkey_from_tss2_public(public_blob), private_blob) {}
36 std::pair<EC_Group, EC_AffinePoint> public_key,
37 std::span<const uint8_t> private_blob) :
38 Botan::TPM2::
PrivateKey(std::move(handle), std::move(sessions), private_blob),
63 std::span<const uint8_t> auth_value,
74 TPM2B_SENSITIVE_CREATE sensitive_data = {
87 TPMT_PUBLIC key_template = {
92 .nameAlg = TPM2_ALG_SHA256,
100 .fixed_parent =
true,
101 .sensitive_data_origin =
true,
102 .user_with_auth =
true,
104 .sign_encrypt =
true,
122 .algorithm = TPM2_ALG_NULL,
123 .keyBits = {.sym = 0},
124 .mode = {.sym = TPM2_ALG_NULL},
136 .scheme = TPM2_ALG_NULL,
137 .details = {.anySig = {.hashAlg = TPM2_ALG_NULL}},
139 .curveID = curve_id.value(),
148 .kdf = {.scheme = TPM2_ALG_NULL, .details = {.kdf2 = {.hashAlg = TPM2_ALG_NULL}}},
153 .unique = {.ecc = {}},
166 .scheme = TPM2_ALG_ECDSA,
169 .hash_name = std::string(hash_name),
170 .padding = std::nullopt,
174size_t signature_length_for_key_handle(
const SessionBundle& sessions,
const Object&
object) {
175 const auto curve_id =
object._public_info(sessions, TPM2_ALG_ECDSA).pub->publicArea.parameters.eccDetail.curveID;
179 throw Invalid_Argument(
Botan::fmt(
"Unsupported ECC curve: {}", curve_id));
181 return 2 * order_bytes.value();
184class EC_Signature_Operation
final :
public Signature_Operation {
186 EC_Signature_Operation(
const Object&
object,
const SessionBundle& sessions, std::string_view hash) :
187 Signature_Operation(object, sessions, make_signature_scheme(hash)) {}
189 size_t signature_length()
const override {
return signature_length_for_key_handle(sessions(), key_handle()); }
191 AlgorithmIdentifier algorithm_identifier()
const override {
193 const std::string full_name =
"ECDSA/" + hash_function();
199 std::vector<uint8_t> marshal_signature(
const TPMT_SIGNATURE& signature)
const override {
202 const auto r =
as_span(signature.signature.ecdsa.signatureR);
203 const auto s =
as_span(signature.signature.ecdsa.signatureS);
204 const auto sig_len = signature_length_for_key_handle(sessions(), key_handle());
212class EC_Verification_Operation
final :
public Verification_Operation {
214 EC_Verification_Operation(
const Object&
object,
const SessionBundle& sessions, std::string_view hash) :
215 Verification_Operation(object, sessions, make_signature_scheme(hash)) {}
218 TPMT_SIGNATURE unmarshal_signature(std::span<const uint8_t> sig_data)
const override {
221 const auto sig_len = signature_length_for_key_handle(sessions(), key_handle());
222 BOTAN_ARG_CHECK(sig_data.size() == sig_len,
"Invalid signature length");
226 .sigAlg = TPM2_ALG_ECDSA,
231 .hash = scheme().details.any.hashAlg,
243 std::string_view provider)
const {
245 return std::make_unique<EC_Verification_Operation>(
handles(),
sessions(), params);
249 std::string_view params,
250 std::string_view provider)
const {
252 return std::make_unique<EC_Signature_Operation>(
handles(),
sessions(), params);
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ARG_CHECK(expr, msg)
const OID & get_curve_oid() const
const EC_Group & domain() const
std::vector< uint8_t > raw_public_key_bits() const override
const EC_Point & public_point() const
static OID from_string(std::string_view str)
std::vector< uint8_t > raw_public_key_bits() const override
static std::unique_ptr< TPM2::PrivateKey > create_unrestricted_transient(const std::shared_ptr< Context > &ctx, const SessionBundle &sessions, std::span< const uint8_t > auth_value, const TPM2::PrivateKey &parent, const EC_Group &group)
std::unique_ptr< Public_Key > public_key() const override
std::unique_ptr< PK_Ops::Signature > create_signature_op(Botan::RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
std::vector< uint8_t > public_key_bits() const override
std::vector< uint8_t > public_key_bits() const override
std::vector< uint8_t > raw_public_key_bits() const override
std::unique_ptr< PK_Ops::Verification > create_verification_op(std::string_view params, std::string_view provider) const override
ESYS_TR transient_handle() const noexcept
static std::unique_ptr< PrivateKey > create_transient_from_template(const std::shared_ptr< Context > &ctx, const SessionBundle &sessions, ESYS_TR parent, const TPMT_PUBLIC &key_template, const TPM2B_SENSITIVE_CREATE &sensitive_data)
std::vector< uint8_t > raw_public_key_bits() const override
const SessionBundle & sessions() const
std::vector< uint8_t > raw_public_key_bits() const override
const Object & handles() const
const SessionBundle & sessions() const
int(* final)(unsigned char *, CTX *)
constexpr T init_empty()
Create an empty TPM2 buffer of the given type.
std::optional< size_t > curve_id_order_byte_size(TPMI_ECC_CURVE curve_id)
TPMI_ALG_HASH get_tpm2_hash_type(std::string_view hash_name)
std::optional< TPM2_ECC_CURVE > get_tpm2_curve_id(const OID &curve_oid)
constexpr void copy_into(T &dest, std::span< const uint8_t > data)
constexpr auto as_span(tpm2_buffer auto &data)
Construct a std::span as a view into a TPM2 buffer.
std::string fmt(std::string_view format, const T &... args)
constexpr auto concat(Rs &&... ranges)
static TPMA_OBJECT render(ObjectAttributes attributes)