9#ifndef BOTAN_TPM2_UTIL_H_ 
   10#define BOTAN_TPM2_UTIL_H_ 
   12#include <botan/bigint.h> 
   13#include <botan/concepts.h> 
   14#include <botan/mem_ops.h> 
   15#include <botan/tpm2_context.h> 
   16#include <botan/tpm2_error.h> 
   17#include <botan/tpm2_object.h> 
   19#include <botan/internal/fmt.h> 
   25#include <tss2/tss2_esys.h> 
   26#include <tss2/tss2_rc.h> 
   35#if defined(TSS2_BASE_RC_CALLBACK_NULL) 
   37   #define BOTAN_TSS2_SUPPORTS_CRYPTO_CALLBACKS 
   40   #define BOTAN_TSS2_SUPPORTS_ERROR_DECODING 
   43#if defined(TPM2_RC_FW_LIMITED) 
   45   #define BOTAN_TSS2_SUPPORTS_SM4_IN_CRYPTO_CALLBACKS 
   56   if(rc != TSS2_RC_SUCCESS) {
 
   57      throw Error(location, rc);
 
 
   71template <
TSS2_RC... expected_errors>
 
   72   requires(
sizeof...(expected_errors) > 0)
 
   75   if(rc == TSS2_RC_SUCCESS) {
 
   83   const bool is_expected_by_caller = ((decoded_rc == expected_errors) || ...);
 
   84   if(is_expected_by_caller) {
 
 
   98   { t.buffer } -> std::convertible_to<const uint8_t*>;
 
   99   { t.size } -> std::convertible_to<size_t>;
 
 
  104   return std::span{data.buffer, data.size};
 
 
  111   data.size = 
static_cast<decltype(data.size)
>(length);
 
 
  117template <tpm2_buffer T>
 
  118constexpr void copy_into(T& dest, std::span<const uint8_t> data) {
 
 
  124template <tpm2_buffer T>
 
  133template <concepts::resizable_
byte_buffer OutT>
 
  136   result.resize(data.size);
 
 
  142template <tpm2_buffer T>
 
  146   result.size = 
static_cast<decltype(result.size)
>(length);
 
 
  152template <tpm2_buffer T>
 
  186            m_object(object), m_persistent(persistent), m_handle(persistent ? 0 : ESYS_TR_NONE) {}
 
 
  194            m_object.handles().persistent = m_handle;
 
  196            m_object.handles().transient = m_handle;
 
 
  206      [[nodiscard]] 
constexpr operator uint32_t*() && 
noexcept { 
return &m_handle; }
 
  209      constexpr bool was_written()
 const { 
return m_handle != (m_persistent ? 0 : ESYS_TR_NONE); }
 
 
  231template <
typename FieldPo
interT, std::
unsigned_
integral MaskT>
 
  232   requires std::is_member_object_pointer_v<FieldPointerT>
 
  238      [[nodiscard]] 
constexpr bool& 
operator()(
auto& 
object) 
const noexcept { 
return object.*
field; }
 
  241      [[nodiscard]] 
constexpr bool operator()(
const auto& 
object) 
const noexcept { 
return object.*
field; }
 
 
  245template <
typename MaskT, 
typename FieldPo
interT>
 
  256template <std::unsigned_integral UnderlyingT,
 
  257          typename AttributeWrapperT,
 
  261      template <std::invocable<const PropMap<
bool AttributeWrapperT::*, UnderlyingT>&> FnT>
 
  262      static constexpr void for_all(
const FnT& fn) {
 
  266      static consteval bool all_single_bit_bitmasks() {
 
  268         for_all([&](
auto&& prop) { result = result && (std::popcount(prop.mask) == 1); });
 
  272      static_assert(all_single_bit_bitmasks(), 
"props... must contain single-bit flags only");
 
  275      static constexpr UnderlyingT 
render(AttributeWrapperT attributes) {
 
  276         UnderlyingT result = 0;
 
  277         for_all([&](
auto&& prop) {
 
  278            if(prop(attributes)) {
 
 
  285      static constexpr AttributeWrapperT 
read(UnderlyingT attributes) {
 
  286         AttributeWrapperT result;
 
  287         for_all([&](
auto&& prop) { prop(result) = (attributes & prop.mask) != 0; });
 
 
 
  292#if defined(BOTAN_HAS_RSA) 
  301inline std::pair<BigInt, BigInt> rsa_pubkey_components_from_tss2_public(
const TPM2B_PUBLIC* public_blob) {
 
  303   const auto& pub = public_blob->publicArea;
 
  304   BOTAN_ARG_CHECK(pub.type == TPM2_ALG_RSA, 
"Public key is not an RSA key");
 
  307   const auto exponent = (pub.parameters.rsaDetail.exponent == 0) ? 65537 : pub.parameters.rsaDetail.exponent;
 
#define BOTAN_ASSERT_NOMSG(expr)
 
#define BOTAN_ASSERT_NONNULL(ptr)
 
#define BOTAN_ARG_CHECK(expr, msg)
 
static constexpr AttributeWrapperT read(UnderlyingT attributes)
 
static constexpr UnderlyingT render(AttributeWrapperT attributes)
 
ObjectSetter(const ObjectSetter &)=delete
 
constexpr ObjectSetter(Object &object, bool persistent=false)
 
ObjectSetter & operator=(ObjectSetter &&)=delete
 
ObjectSetter(ObjectSetter &&)=delete
 
constexpr ~ObjectSetter() noexcept
 
ObjectSetter & operator=(const ObjectSetter &)=delete
 
PropMap(MaskT, FieldPointerT) -> PropMap< MaskT, FieldPointerT >
Deduction guide to simplify the creation of PropMap instances.
 
constexpr T init_empty()
Create an empty TPM2 buffer of the given type.
 
constexpr void check_rc(std::string_view location, TSS2_RC rc)
 
constexpr auto out_persistent_handle(Object &object)
 
std::unique_ptr< T, esys_liberator > unique_esys_ptr
A unique pointer type for ESYS handles that automatically frees the handle.
 
TSS2_RC get_raw_rc(TSS2_RC rc)
 
constexpr T init_with_size(size_t length)
Create a TPM2 buffer of a given type and length.
 
constexpr auto out_transient_handle(Object &object)
 
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.
 
constexpr TSS2_RC check_rc_expecting(std::string_view location, TSS2_RC rc)
 
constexpr void copy_mem(T *out, const T *in, size_t n)
 
constexpr void clear_bytes(void *ptr, size_t bytes)
 
std::optional< TPM2_HANDLE > persistent
 
constexpr bool operator()(const auto &object) const noexcept
Read-only access the boolean member 'field' from the given object.
 
constexpr bool & operator()(auto &object) const noexcept
Access the boolean member 'field' from the given object.
 
unique_esys_ptr< TPM2B_PUBLIC > pub
 
unique_esys_ptr< TPM2B_NAME > qualified_name
 
unique_esys_ptr< TPM2B_NAME > name
 
void operator()(void *handle)
 
uint32_t ESYS_TR
Forward declaration of TSS2 type for convenience.
 
uint32_t TSS2_RC
Forward declaration of TSS2 type for convenience.