_ZN5Botan17ct_expand_top_bitITkNSt3__117unsigned_integralEhEET_S2_:
   28|   343k|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|   343k|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|   343k|   return static_cast<T>(0) - top;
   31|   343k|}
_ZN5Botan17ct_expand_top_bitITkNSt3__117unsigned_integralEmEET_S2_:
   28|  29.6k|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|  29.6k|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|  29.6k|   return static_cast<T>(0) - top;
   31|  29.6k|}
_ZN5Botan6chooseITkNSt3__117unsigned_integralEmEET_S2_S2_S2_:
  216|    590|BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b) {
  217|       |   //return (mask & a) | (~mask & b);
  218|    590|   return (b ^ (mask & (a ^ b)));
  219|    590|}
_ZN5Botan10ct_is_zeroITkNSt3__117unsigned_integralEhEET_S2_:
   37|   343k|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|   343k|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|   343k|}
_ZN5Botan10ct_is_zeroITkNSt3__117unsigned_integralEmEET_S2_:
   37|  14.7k|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|  14.7k|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|  14.7k|}
_ZN5Botan17ct_expand_top_bitITkNSt3__117unsigned_integralEtEET_S2_:
   28|  31.7k|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|  31.7k|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|  31.7k|   return static_cast<T>(0) - top;
   31|  31.7k|}
_ZN5Botan10ct_is_zeroITkNSt3__117unsigned_integralEtEET_S2_:
   37|  15.7k|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|  15.7k|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|  15.7k|}

_ZN5Botan2CT6poisonIhEEvPKT_m:
   56|    590|constexpr inline void poison(const T* p, size_t n) {
   57|       |#if defined(BOTAN_HAS_VALGRIND)
   58|       |   if(!std::is_constant_evaluated()) {
   59|       |      VALGRIND_MAKE_MEM_UNDEFINED(p, n * sizeof(T));
   60|       |   }
   61|       |#endif
   62|       |
   63|    590|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  144|    590|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   64|    590|}
_ZN5Botan2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS6_EEEDaDpRKS6_:
  222|    590|[[nodiscard]] constexpr auto scoped_poison(const Ts&... xs) {
  223|    590|   auto scope = scoped_cleanup([&] { unpoison_all(xs...); });
  224|    590|   poison_all(xs...);
  225|    590|   return scope;
  226|    590|}
_ZN5Botan2CT10poison_allITpTkNS0_10poisonableEJNSt3__14spanIKhLm18446744073709551615EEEEQgtsZT_Li0EEEvDpRKT_:
  201|    590|constexpr void poison_all(const Ts&... ts) {
  202|    590|   (poison(ts), ...);
  203|    590|}
_ZN5Botan2CT6poisonITkNS_6ranges14spanable_rangeENSt3__14spanIKhLm18446744073709551615EEEQaasr3stdE23is_trivially_copyable_vINS3_11conditionalIXsr21__is_primary_templateINS3_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS3_6ranges5__cpo5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENS3_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEnt17custom_poisonableISB_EEEvRKSB_:
  121|    590|constexpr void poison(const R& r) {
  122|    590|   const std::span s{r};
  123|    590|   poison(s.data(), s.size());
  124|    590|}
_ZN5Botan2CT16driveby_unpoisonITkNS0_12unpoisonableEmEEDcOT_Qsr3stdE21is_rvalue_reference_vIDtfp_EE:
  245|    590|{
  246|    590|   unpoison(v);
  247|    590|   return std::forward<T>(v);
  248|    590|}
_ZN5Botan2CT8unpoisonITkNSt3__18integralEmEEvRKT_:
  112|    590|constexpr void unpoison(const T& p) {
  113|    590|   unpoison(&p, 1);
  114|    590|}
_ZN5Botan2CT8unpoisonImEEvPKT_m:
   67|    590|constexpr inline void unpoison(const T* p, size_t n) {
   68|       |#if defined(BOTAN_HAS_VALGRIND)
   69|       |   if(!std::is_constant_evaluated()) {
   70|       |      VALGRIND_MAKE_MEM_DEFINED(p, n * sizeof(T));
   71|       |   }
   72|       |#endif
   73|       |
   74|    590|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  144|    590|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   75|    590|}
_ZN5Botan2CT4MaskIhEC2Eh:
  637|   859k|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskIhE5valueEv:
  630|  1.20M|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZN5Botan2CT4MaskImE5is_gtEmm:
  458|  5.22k|      static constexpr Mask<T> is_gt(T x, T y) { return Mask<T>::is_lt(y, x); }
_ZN5Botan2CT4MaskImE5is_ltEmm:
  450|  14.8k|      static constexpr Mask<T> is_lt(T x, T y) {
  451|  14.8k|         T u = x ^ ((x ^ y) | ((x - y) ^ x));
  452|  14.8k|         return Mask<T>::expand_top_bit(u);
  453|  14.8k|      }
_ZN5Botan2CT4MaskImE14expand_top_bitEm:
  415|  14.8k|      static constexpr Mask<T> expand_top_bit(T v) { return Mask<T>(ct_expand_top_bit<T>(v)); }
_ZN5Botan2CT4MaskImEC2Em:
  637|  68.4k|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZN5Botan2CT4MaskImE8is_equalEmm:
  442|  9.62k|      static constexpr Mask<T> is_equal(T x, T y) {
  443|  9.62k|         const T diff = value_barrier(x) ^ value_barrier(y);
  444|  9.62k|         return Mask<T>::is_zero(diff);
  445|  9.62k|      }
_ZN5Botan2CT4MaskImE6is_gteEmm:
  468|  9.62k|      static constexpr Mask<T> is_gte(T x, T y) { return ~Mask<T>::is_lt(x, y); }
_ZNK5Botan2CT4MaskImEcoEv:
  533|  24.2k|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskImE5valueEv:
  630|  68.4k|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZNK5Botan2CT4MaskImE6selectEmm:
  548|    590|      constexpr T select(T x, T y) const { return choose(value(), x, y); }
_ZN5Botan2CT4MaskImE6expandEm:
  392|  4.81k|      static constexpr Mask<T> expand(T v) { return ~Mask<T>::is_zero(value_barrier<T>(v)); }
_ZN5Botan2CT4MaskIhE7clearedEv:
  387|    358|      static constexpr Mask<T> cleared() { return Mask<T>(0); }
_ZN5Botan2CT4MaskIhE8is_equalEhh:
  442|   171k|      static constexpr Mask<T> is_equal(T x, T y) {
  443|   171k|         const T diff = value_barrier(x) ^ value_barrier(y);
  444|   171k|         return Mask<T>::is_zero(diff);
  445|   171k|      }
_ZN5Botan2CT4MaskIhE7is_zeroEh:
  437|   343k|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZNK5Botan2CT4MaskIhE17if_not_set_returnEh:
  543|   171k|      constexpr T if_not_set_return(T x) const { return ~value() & x; }
_ZNK5Botan2CT4MaskIhEcoEv:
  533|   343k|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZN5Botan2CT4MaskImE6expandIhEES2_NS1_IT_EE:
  429|    179|      static constexpr Mask<T> expand(Mask<U> m) {
  430|    179|         static_assert(sizeof(U) < sizeof(T), "sizes ok");
  431|    179|         return ~Mask<T>::is_zero(m.value());
  432|    179|      }
_ZN5Botan2CT4MaskImE7is_zeroEm:
  437|  14.7k|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZN5Botan2CT8unpoisonIhEEvPKT_m:
   67|    590|constexpr inline void unpoison(const T* p, size_t n) {
   68|       |#if defined(BOTAN_HAS_VALGRIND)
   69|       |   if(!std::is_constant_evaluated()) {
   70|       |      VALGRIND_MAKE_MEM_DEFINED(p, n * sizeof(T));
   71|       |   }
   72|       |#endif
   73|       |
   74|    590|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  144|    590|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   75|    590|}
_ZZN5Botan2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS6_EEEDaDpRKS6_ENKUlvE_clEv:
  223|    590|   auto scope = scoped_cleanup([&] { unpoison_all(xs...); });
_ZN5Botan2CT12unpoison_allITpTkNS0_12unpoisonableEJNSt3__14spanIKhLm18446744073709551615EEEEQgtsZT_Li0EEEvDpRKT_:
  207|    590|constexpr void unpoison_all(const Ts&... ts) {
  208|    590|   (unpoison(ts), ...);
  209|    590|}
_ZN5Botan2CT8unpoisonITkNS_6ranges14spanable_rangeENSt3__14spanIKhLm18446744073709551615EEEQaasr3stdE23is_trivially_copyable_vINS3_11conditionalIXsr21__is_primary_templateINS3_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS3_6ranges5__cpo5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENS3_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEnt19custom_unpoisonableISB_EEEvRKSB_:
  128|    590|constexpr void unpoison(const R& r) {
  129|    590|   const std::span s{r};
  130|    590|   unpoison(s.data(), s.size());
  131|    590|}
_ZN5Botan2CTanENS0_4MaskImEES2_:
  518|  14.4k|      friend Mask<T> operator&(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() & y.value()); }
_ZN5Botan2CT4MaskImEoRES2_:
  510|  14.4k|      Mask<T>& operator|=(Mask<T> o) {
  511|  14.4k|         m_mask |= o.value();
  512|  14.4k|         return (*this);
  513|  14.4k|      }
_ZN5Botan2CT4MaskIhEoRES2_:
  510|   343k|      Mask<T>& operator|=(Mask<T> o) {
  511|   343k|         m_mask |= o.value();
  512|   343k|         return (*this);
  513|   343k|      }
_ZN5Botan2CTanENS0_4MaskIhEES2_:
  518|   171k|      friend Mask<T> operator&(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() & y.value()); }
_ZN5Botan2CTorENS0_4MaskImEES2_:
  528|    137|      friend Mask<T> operator|(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() | y.value()); }
_ZN5Botan2CT4MaskItE5is_ltEtt:
  450|  15.9k|      static constexpr Mask<T> is_lt(T x, T y) {
  451|  15.9k|         T u = x ^ ((x ^ y) | ((x - y) ^ x));
  452|  15.9k|         return Mask<T>::expand_top_bit(u);
  453|  15.9k|      }
_ZN5Botan2CT4MaskItE14expand_top_bitEt:
  415|  15.9k|      static constexpr Mask<T> expand_top_bit(T v) { return Mask<T>(ct_expand_top_bit<T>(v)); }
_ZN5Botan2CT4MaskItEC2Et:
  637|  78.9k|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZN5Botan2CT4MaskItE6is_lteEtt:
  463|  15.7k|      static constexpr Mask<T> is_lte(T x, T y) { return ~Mask<T>::is_gt(x, y); }
_ZN5Botan2CT4MaskItE5is_gtEtt:
  458|  15.7k|      static constexpr Mask<T> is_gt(T x, T y) { return Mask<T>::is_lt(y, x); }
_ZN5Botan2CT4MaskItE8is_equalEtt:
  442|  15.7k|      static constexpr Mask<T> is_equal(T x, T y) {
  443|  15.7k|         const T diff = value_barrier(x) ^ value_barrier(y);
  444|  15.7k|         return Mask<T>::is_zero(diff);
  445|  15.7k|      }
_ZN5Botan2CT4MaskItE7is_zeroEt:
  437|  15.7k|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZNK5Botan2CT4MaskItEcoEv:
  533|  31.4k|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskItE5valueEv:
  630|  78.9k|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZNK5Botan2CT4MaskItE17if_not_set_returnEt:
  543|    206|      constexpr T if_not_set_return(T x) const { return ~value() & x; }
_ZN5Botan2CTanENS0_4MaskItEES2_:
  518|  15.7k|      friend Mask<T> operator&(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() & y.value()); }
_ZN5Botan2CT4MaskItEoRES2_:
  510|  15.7k|      Mask<T>& operator|=(Mask<T> o) {
  511|  15.7k|         m_mask |= o.value();
  512|  15.7k|         return (*this);
  513|  15.7k|      }

_ZNK5Botan13PKCS7_Padding15valid_blocksizeEm:
  110|    343|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (110:64): [True: 316, False: 27]
  |  Branch (110:74): [True: 274, False: 42]
  ------------------
_ZNK5Botan17ANSI_X923_Padding15valid_blocksizeEm:
  124|    343|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (124:64): [True: 316, False: 27]
  |  Branch (124:74): [True: 274, False: 42]
  ------------------
_ZNK5Botan19OneAndZeros_Padding15valid_blocksizeEm:
  138|    385|      bool valid_blocksize(size_t bs) const override { return (bs > 2); }
_ZNK5Botan11ESP_Padding15valid_blocksizeEm:
  152|    343|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (152:64): [True: 316, False: 27]
  |  Branch (152:74): [True: 274, False: 42]
  ------------------

_ZN5Botan14scoped_cleanupIZNS_2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS7_EEEDaDpRKS7_EUlvE_EC2ESB_:
   26|    590|      explicit scoped_cleanup(FunT cleanup) : m_cleanup(std::move(cleanup)) {}
_ZN5Botan14scoped_cleanupIZNS_2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS7_EEEDaDpRKS7_EUlvE_EC2EOSC_:
   32|    590|      scoped_cleanup(scoped_cleanup&& other) noexcept : m_cleanup(std::move(other.m_cleanup)) { other.disengage(); }
_ZN5Botan14scoped_cleanupIZNS_2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS7_EEEDaDpRKS7_EUlvE_E9disengageEv:
   43|    590|      void disengage() noexcept { m_cleanup.reset(); }
_ZN5Botan14scoped_cleanupIZNS_2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS7_EEEDaDpRKS7_EUlvE_ED2Ev:
   34|  1.18k|      ~scoped_cleanup() {
   35|  1.18k|         if(m_cleanup.has_value()) {
  ------------------
  |  Branch (35:13): [True: 590, False: 590]
  ------------------
   36|    590|            (*m_cleanup)();  // NOLINT(bugprone-exception-escape) clang-tidy bug
   37|    590|         }
   38|  1.18k|      }

_ZN5Botan2CT13value_barrierITkNSt3__117unsigned_integralEhQntsr3stdE7same_asIbT_EEES3_S3_:
   43|  2.23M|constexpr inline T value_barrier(T x) {
   44|  2.23M|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (44:7): [Folded, False: 2.23M]
  ------------------
   45|      0|      return x;
   46|  2.23M|   } else {
   47|  2.23M|#if defined(BOTAN_CT_VALUE_BARRIER_USE_ASM)
   48|       |      /*
   49|       |      * We may want a "stronger" statement such as
   50|       |      *     asm volatile("" : "+r,m"(x) : : "memory);
   51|       |      * (see https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.html)
   52|       |      * however the current approach seems sufficient with current compilers,
   53|       |      * and is minimally damaging with regards to degrading code generation.
   54|       |      */
   55|  2.23M|      asm("" : "+r"(x) : /* no input */);  // NOLINT(*-no-assembler)
   56|  2.23M|      return x;
   57|       |#elif defined(BOTAN_CT_VALUE_BARRIER_USE_VOLATILE)
   58|       |      volatile T vx = x;
   59|       |      return vx;
   60|       |#else
   61|       |      return x;
   62|       |#endif
   63|  2.23M|   }
   64|  2.23M|}
_ZN5Botan2CT13value_barrierITkNSt3__117unsigned_integralEmQntsr3stdE7same_asIbT_EEES3_S3_:
   43|   136k|constexpr inline T value_barrier(T x) {
   44|   136k|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (44:7): [Folded, False: 136k]
  ------------------
   45|      0|      return x;
   46|   136k|   } else {
   47|   136k|#if defined(BOTAN_CT_VALUE_BARRIER_USE_ASM)
   48|       |      /*
   49|       |      * We may want a "stronger" statement such as
   50|       |      *     asm volatile("" : "+r,m"(x) : : "memory);
   51|       |      * (see https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.html)
   52|       |      * however the current approach seems sufficient with current compilers,
   53|       |      * and is minimally damaging with regards to degrading code generation.
   54|       |      */
   55|   136k|      asm("" : "+r"(x) : /* no input */);  // NOLINT(*-no-assembler)
   56|   136k|      return x;
   57|       |#elif defined(BOTAN_CT_VALUE_BARRIER_USE_VOLATILE)
   58|       |      volatile T vx = x;
   59|       |      return vx;
   60|       |#else
   61|       |      return x;
   62|       |#endif
   63|   136k|   }
   64|   136k|}
_ZN5Botan2CT13value_barrierITkNSt3__117unsigned_integralEtQntsr3stdE7same_asIbT_EEES3_S3_:
   43|   157k|constexpr inline T value_barrier(T x) {
   44|   157k|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (44:7): [Folded, False: 157k]
  ------------------
   45|      0|      return x;
   46|   157k|   } else {
   47|   157k|#if defined(BOTAN_CT_VALUE_BARRIER_USE_ASM)
   48|       |      /*
   49|       |      * We may want a "stronger" statement such as
   50|       |      *     asm volatile("" : "+r,m"(x) : : "memory);
   51|       |      * (see https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.html)
   52|       |      * however the current approach seems sufficient with current compilers,
   53|       |      * and is minimally damaging with regards to degrading code generation.
   54|       |      */
   55|   157k|      asm("" : "+r"(x) : /* no input */);  // NOLINT(*-no-assembler)
   56|   157k|      return x;
   57|       |#elif defined(BOTAN_CT_VALUE_BARRIER_USE_VOLATILE)
   58|       |      volatile T vx = x;
   59|       |      return vx;
   60|       |#else
   61|       |      return x;
   62|       |#endif
   63|   157k|   }
   64|   157k|}

_ZN5Botan13ignore_paramsIJPKmmEEEvDpRKT_:
  142|    590|constexpr void ignore_params([[maybe_unused]] const T&... args) {}
_ZN5Botan13ignore_paramsIJPKhmEEEvDpRKT_:
  142|  1.18k|constexpr void ignore_params([[maybe_unused]] const T&... args) {}

LLVMFuzzerInitialize:
   28|      2|extern "C" int LLVMFuzzerInitialize(int* /*argc*/, char*** /*argv*/) {
   29|       |   /*
   30|       |   * This disables the mlock pool, as overwrites within the pool are
   31|       |   * opaque to ASan or other instrumentation.
   32|       |   */
   33|      2|   ::setenv("BOTAN_MLOCK_POOL_SIZE", "0", 1);
   34|      2|   return 0;
   35|      2|}
LLVMFuzzerTestOneInput:
   39|    216|extern "C" int LLVMFuzzerTestOneInput(const uint8_t in[], size_t len) {
   40|    216|   if(len <= max_fuzzer_input_size) {
  ------------------
  |  Branch (40:7): [True: 206, False: 10]
  ------------------
   41|    206|      try {
   42|    206|         fuzz(std::span<const uint8_t>(in, len));
   43|    206|      } catch(const std::exception& e) {
   44|      0|         std::cerr << "Uncaught exception from fuzzer driver " << e.what() << "\n";
   45|      0|         abort();
   46|      0|      } catch(...) {
   47|      0|         std::cerr << "Uncaught exception from fuzzer driver (unknown type)\n";
   48|      0|         abort();
   49|      0|      }
   50|    206|   }
   51|    216|   return 0;
   52|    216|}

_Z4fuzzNSt3__14spanIKhLm18446744073709551615EEE:
  132|    206|void fuzz(std::span<const uint8_t> in) {
  133|    206|   static const Botan::PKCS7_Padding pkcs7;
  134|    206|   static const Botan::ANSI_X923_Padding x923;
  135|    206|   static const Botan::OneAndZeros_Padding oneandzero;
  136|    206|   static const Botan::ESP_Padding esp;
  137|       |
  138|    206|   const size_t len = in.size();
  139|       |
  140|    206|   if(pkcs7.valid_blocksize(len)) {
  ------------------
  |  Branch (140:7): [True: 137, False: 69]
  ------------------
  141|    137|      const size_t ct_pkcs7 = pkcs7.unpad(in);
  142|    137|      const size_t ref_pkcs7 = ref_pkcs7_unpad(in);
  143|    137|      FUZZER_ASSERT_EQUAL(ct_pkcs7, ref_pkcs7);
  ------------------
  |  |   79|    137|   do {                                                                                      \
  |  |   80|    137|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 137]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\n"); \
  |  |  ------------------
  |  |  |  |   70|      0|   do {                                                                                                       \
  |  |  |  |   71|      0|      std::cerr << expr << " @ Line " << __LINE__ << " in " << __FILE__ << "\n"; /* NOLINT(*-macro-paren*) */ \
  |  |  |  |   72|      0|      abort();                                                                                                \
  |  |  |  |   73|      0|   } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (73:12): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|    137|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 137]
  |  |  ------------------
  ------------------
  144|    137|   }
  145|       |
  146|    206|   if(x923.valid_blocksize(len)) {
  ------------------
  |  Branch (146:7): [True: 137, False: 69]
  ------------------
  147|    137|      const size_t ct_x923 = x923.unpad(in);
  148|    137|      const size_t ref_x923 = ref_x923_unpad(in);
  149|    137|      FUZZER_ASSERT_EQUAL(ct_x923, ref_x923);
  ------------------
  |  |   79|    137|   do {                                                                                      \
  |  |   80|    137|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 137]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\n"); \
  |  |  ------------------
  |  |  |  |   70|      0|   do {                                                                                                       \
  |  |  |  |   71|      0|      std::cerr << expr << " @ Line " << __LINE__ << " in " << __FILE__ << "\n"; /* NOLINT(*-macro-paren*) */ \
  |  |  |  |   72|      0|      abort();                                                                                                \
  |  |  |  |   73|      0|   } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (73:12): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|    137|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 137]
  |  |  ------------------
  ------------------
  150|    137|   }
  151|       |
  152|    206|   if(oneandzero.valid_blocksize(len)) {
  ------------------
  |  Branch (152:7): [True: 179, False: 27]
  ------------------
  153|    179|      const size_t ct_oneandzero = oneandzero.unpad(in);
  154|    179|      const size_t ref_oneandzero = ref_oneandzero_unpad(in);
  155|    179|      FUZZER_ASSERT_EQUAL(ct_oneandzero, ref_oneandzero);
  ------------------
  |  |   79|    179|   do {                                                                                      \
  |  |   80|    179|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 179]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\n"); \
  |  |  ------------------
  |  |  |  |   70|      0|   do {                                                                                                       \
  |  |  |  |   71|      0|      std::cerr << expr << " @ Line " << __LINE__ << " in " << __FILE__ << "\n"; /* NOLINT(*-macro-paren*) */ \
  |  |  |  |   72|      0|      abort();                                                                                                \
  |  |  |  |   73|      0|   } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (73:12): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|    179|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 179]
  |  |  ------------------
  ------------------
  156|    179|   }
  157|       |
  158|    206|   if(esp.valid_blocksize(len)) {
  ------------------
  |  Branch (158:7): [True: 137, False: 69]
  ------------------
  159|    137|      const size_t ct_esp = esp.unpad(in);
  160|    137|      const size_t ref_esp = ref_esp_unpad(in);
  161|    137|      FUZZER_ASSERT_EQUAL(ct_esp, ref_esp);
  ------------------
  |  |   79|    137|   do {                                                                                      \
  |  |   80|    137|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 137]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\n"); \
  |  |  ------------------
  |  |  |  |   70|      0|   do {                                                                                                       \
  |  |  |  |   71|      0|      std::cerr << expr << " @ Line " << __LINE__ << " in " << __FILE__ << "\n"; /* NOLINT(*-macro-paren*) */ \
  |  |  |  |   72|      0|      abort();                                                                                                \
  |  |  |  |   73|      0|   } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (73:12): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|    137|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 137]
  |  |  ------------------
  ------------------
  162|    137|   }
  163|       |
  164|    206|   const uint16_t ct_cbc = Botan::TLS::check_tls_cbc_padding(in.data(), len);
  165|    206|   const uint16_t ref_cbc = ref_tls_cbc_unpad(in);
  166|    206|   FUZZER_ASSERT_EQUAL(ct_cbc, ref_cbc);
  ------------------
  |  |   79|    206|   do {                                                                                      \
  |  |   80|    206|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 206]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\n"); \
  |  |  ------------------
  |  |  |  |   70|      0|   do {                                                                                                       \
  |  |  |  |   71|      0|      std::cerr << expr << " @ Line " << __LINE__ << " in " << __FILE__ << "\n"; /* NOLINT(*-macro-paren*) */ \
  |  |  |  |   72|      0|      abort();                                                                                                \
  |  |  |  |   73|      0|   } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (73:12): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|    206|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 206]
  |  |  ------------------
  ------------------
  167|    206|}
mode_padding.cpp:_ZN12_GLOBAL__N_115ref_pkcs7_unpadENSt3__14spanIKhLm18446744073709551615EEE:
   14|    137|size_t ref_pkcs7_unpad(std::span<const uint8_t> in) {
   15|    137|   if(in.size() <= 2) {
  ------------------
  |  Branch (15:7): [True: 0, False: 137]
  ------------------
   16|      0|      return in.size();
   17|      0|   }
   18|    137|   const size_t len = in.size();
   19|       |
   20|    137|   const size_t padding_length = in[len - 1];
   21|       |
   22|    137|   if(padding_length == 0 || padding_length > len) {
  ------------------
  |  Branch (22:7): [True: 28, False: 109]
  |  Branch (22:30): [True: 24, False: 85]
  ------------------
   23|     52|      return len;
   24|     52|   }
   25|       |
   26|     85|   const size_t padding_start = len - padding_length;
   27|       |
   28|    498|   for(size_t i = padding_start; i != len; ++i) {
  ------------------
  |  Branch (28:34): [True: 474, False: 24]
  ------------------
   29|    474|      if(in[i] != padding_length) {
  ------------------
  |  Branch (29:10): [True: 61, False: 413]
  ------------------
   30|     61|         return len;
   31|     61|      }
   32|    474|   }
   33|       |
   34|     24|   return len - padding_length;
   35|     85|}
mode_padding.cpp:_ZN12_GLOBAL__N_114ref_x923_unpadENSt3__14spanIKhLm18446744073709551615EEE:
   37|    137|size_t ref_x923_unpad(std::span<const uint8_t> in) {
   38|    137|   const size_t len = in.size();
   39|    137|   if(len <= 2) {
  ------------------
  |  Branch (39:7): [True: 0, False: 137]
  ------------------
   40|      0|      return len;
   41|      0|   }
   42|       |
   43|    137|   const size_t padding_length = in[len - 1];
   44|       |
   45|    137|   if(padding_length == 0 || padding_length > len) {
  ------------------
  |  Branch (45:7): [True: 28, False: 109]
  |  Branch (45:30): [True: 24, False: 85]
  ------------------
   46|     52|      return len;
   47|     52|   }
   48|     85|   const size_t padding_start = len - padding_length;
   49|       |
   50|    730|   for(size_t i = padding_start; i != len - 1; ++i) {
  ------------------
  |  Branch (50:34): [True: 716, False: 14]
  ------------------
   51|    716|      if(in[i] != 0) {
  ------------------
  |  Branch (51:10): [True: 71, False: 645]
  ------------------
   52|     71|         return len;
   53|     71|      }
   54|    716|   }
   55|       |
   56|     14|   return len - padding_length;
   57|     85|}
mode_padding.cpp:_ZN12_GLOBAL__N_120ref_oneandzero_unpadENSt3__14spanIKhLm18446744073709551615EEE:
   59|    179|size_t ref_oneandzero_unpad(std::span<const uint8_t> in) {
   60|    179|   const size_t len = in.size();
   61|    179|   if(len <= 2) {
  ------------------
  |  Branch (61:7): [True: 0, False: 179]
  ------------------
   62|      0|      return len;
   63|      0|   }
   64|       |
   65|    179|   size_t idx = len - 1;
   66|       |
   67|  1.17k|   for(;;) {
   68|  1.17k|      if(in[idx] == 0) {
  ------------------
  |  Branch (68:10): [True: 993, False: 177]
  ------------------
   69|    993|         if(idx == 0) {
  ------------------
  |  Branch (69:13): [True: 2, False: 991]
  ------------------
   70|      2|            return len;
   71|      2|         }
   72|    991|         idx -= 1;
   73|    991|         continue;
   74|    993|      } else if(in[idx] == 0x80) {
  ------------------
  |  Branch (74:17): [True: 5, False: 172]
  ------------------
   75|      5|         return idx;
   76|    172|      } else {
   77|    172|         return len;
   78|    172|      }
   79|  1.17k|   }
   80|       |
   81|      0|   return len;
   82|    179|}
mode_padding.cpp:_ZN12_GLOBAL__N_113ref_esp_unpadENSt3__14spanIKhLm18446744073709551615EEE:
   84|    137|size_t ref_esp_unpad(std::span<const uint8_t> in) {
   85|    137|   const size_t len = in.size();
   86|    137|   if(len <= 2) {
  ------------------
  |  Branch (86:7): [True: 0, False: 137]
  ------------------
   87|      0|      return len;
   88|      0|   }
   89|       |
   90|    137|   const size_t padding_bytes = in[len - 1];
   91|       |
   92|    137|   if(padding_bytes == 0 || padding_bytes > len) {
  ------------------
  |  Branch (92:7): [True: 28, False: 109]
  |  Branch (92:29): [True: 24, False: 85]
  ------------------
   93|     52|      return len;
   94|     52|   }
   95|       |
   96|     85|   const size_t padding_start = len - padding_bytes;
   97|    225|   for(size_t i = padding_start; i != len; ++i) {
  ------------------
  |  Branch (97:34): [True: 210, False: 15]
  ------------------
   98|    210|      if(in[i] != (i - padding_start + 1)) {
  ------------------
  |  Branch (98:10): [True: 70, False: 140]
  ------------------
   99|     70|         return len;
  100|     70|      }
  101|    210|   }
  102|       |
  103|     15|   return len - padding_bytes;
  104|     85|}
mode_padding.cpp:_ZN12_GLOBAL__N_117ref_tls_cbc_unpadENSt3__14spanIKhLm18446744073709551615EEE:
  106|    206|uint16_t ref_tls_cbc_unpad(std::span<const uint8_t> in) {
  107|    206|   const size_t len = in.size();
  108|    206|   if(len == 0) {
  ------------------
  |  Branch (108:7): [True: 0, False: 206]
  ------------------
  109|      0|      return 0;
  110|      0|   }
  111|       |
  112|    206|   const size_t padding_length = in[(len - 1)];
  113|       |
  114|    206|   if(padding_length >= len) {
  ------------------
  |  Branch (114:7): [True: 74, False: 132]
  ------------------
  115|     74|      return 0;
  116|     74|   }
  117|       |
  118|       |   /*
  119|       |   * TLS v1.0 and up require all the padding bytes be the same value
  120|       |   * and allows up to 255 bytes.
  121|       |   */
  122|    783|   for(size_t i = 0; i != 1 + padding_length; ++i) {
  ------------------
  |  Branch (122:22): [True: 730, False: 53]
  ------------------
  123|    730|      if(in[(len - i - 1)] != padding_length) {
  ------------------
  |  Branch (123:10): [True: 79, False: 651]
  ------------------
  124|     79|         return 0;
  125|     79|      }
  126|    730|   }
  127|     53|   return padding_length + 1;
  128|    132|}

_ZNK5Botan28BlockCipherModePaddingMethod5unpadENSt3__14spanIKhLm18446744073709551615EEE:
   60|    590|size_t BlockCipherModePaddingMethod::unpad(std::span<const uint8_t> last_block) const {
   61|    590|   if(!valid_blocksize(last_block.size())) {
  ------------------
  |  Branch (61:7): [True: 0, False: 590]
  ------------------
   62|      0|      return last_block.size();
   63|      0|   }
   64|       |
   65|    590|   auto poison = CT::scoped_poison(last_block);
   66|    590|   return CT::driveby_unpoison(remove_padding(last_block));
   67|    590|}
_ZNK5Botan13PKCS7_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
   92|    137|size_t PKCS7_Padding::remove_padding(std::span<const uint8_t> input) const {
   93|    137|   const size_t BS = input.size();
   94|    137|   const uint8_t last_byte = input.back();
   95|       |
   96|       |   /*
   97|       |   The input should == the block size so if the last byte exceeds
   98|       |   that then the padding is certainly invalid
   99|       |   */
  100|    137|   auto bad_input = CT::Mask<size_t>::is_gt(last_byte, BS);
  101|       |
  102|    137|   const size_t pad_pos = BS - last_byte;
  103|       |
  104|  4.95k|   for(size_t i = 0; i != BS - 1; ++i) {
  ------------------
  |  Branch (104:22): [True: 4.81k, False: 137]
  ------------------
  105|       |      // Does this byte equal the expected pad byte?
  106|  4.81k|      const auto pad_eq = CT::Mask<size_t>::is_equal(input[i], last_byte);
  107|       |
  108|       |      // Ignore values that are not part of the padding
  109|  4.81k|      const auto in_range = CT::Mask<size_t>::is_gte(i, pad_pos);
  110|  4.81k|      bad_input |= in_range & (~pad_eq);
  111|  4.81k|   }
  112|       |
  113|    137|   return bad_input.select(BS, pad_pos);
  114|    137|}
_ZNK5Botan17ANSI_X923_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
  141|    137|size_t ANSI_X923_Padding::remove_padding(std::span<const uint8_t> input) const {
  142|    137|   const size_t BS = input.size();
  143|    137|   const size_t last_byte = input.back();
  144|       |
  145|    137|   auto bad_input = CT::Mask<size_t>::is_gt(last_byte, BS);
  146|       |
  147|    137|   const size_t pad_pos = BS - last_byte;
  148|       |
  149|  4.95k|   for(size_t i = 0; i != BS - 1; ++i) {
  ------------------
  |  Branch (149:22): [True: 4.81k, False: 137]
  ------------------
  150|       |      // Ignore values that are not part of the padding
  151|  4.81k|      const auto in_range = CT::Mask<size_t>::is_gte(i, pad_pos);
  152|  4.81k|      const auto pad_is_nonzero = CT::Mask<size_t>::expand(input[i]);
  153|  4.81k|      bad_input |= pad_is_nonzero & in_range;
  154|  4.81k|   }
  155|       |
  156|    137|   return bad_input.select(BS, pad_pos);
  157|    137|}
_ZNK5Botan19OneAndZeros_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
  180|    179|size_t OneAndZeros_Padding::remove_padding(std::span<const uint8_t> input) const {
  181|    179|   const size_t BS = input.size();
  182|    179|   auto bad_input = CT::Mask<uint8_t>::cleared();
  183|    179|   auto seen_0x80 = CT::Mask<uint8_t>::cleared();
  184|       |
  185|    179|   size_t pad_pos = BS - 1;
  186|       |
  187|   172k|   for(size_t i = BS; i != 0; --i) {
  ------------------
  |  Branch (187:23): [True: 171k, False: 179]
  ------------------
  188|   171k|      const auto is_0x80 = CT::Mask<uint8_t>::is_equal(input[i - 1], 0x80);
  189|   171k|      const auto is_zero = CT::Mask<uint8_t>::is_zero(input[i - 1]);
  190|       |
  191|   171k|      seen_0x80 |= is_0x80;
  192|   171k|      pad_pos -= seen_0x80.if_not_set_return(1);
  193|   171k|      bad_input |= ~seen_0x80 & ~is_zero;
  194|   171k|   }
  195|    179|   bad_input |= ~seen_0x80;
  196|       |
  197|    179|   return CT::Mask<size_t>::expand(bad_input).select(BS, pad_pos);
  198|    179|}
_ZNK5Botan11ESP_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
  225|    137|size_t ESP_Padding::remove_padding(std::span<const uint8_t> input) const {
  226|    137|   const size_t BS = input.size();
  227|    137|   const uint8_t last_byte = input.back();
  228|       |
  229|    137|   auto bad_input = CT::Mask<size_t>::is_zero(last_byte) | CT::Mask<size_t>::is_gt(last_byte, BS);
  230|       |
  231|    137|   const size_t pad_pos = BS - last_byte;
  232|  4.95k|   for(size_t i = BS - 1; i != 0; --i) {
  ------------------
  |  Branch (232:27): [True: 4.81k, False: 137]
  ------------------
  233|  4.81k|      const auto in_range = CT::Mask<size_t>::is_gt(i, pad_pos);
  234|  4.81k|      const auto incrementing = CT::Mask<size_t>::is_equal(input[i - 1], input[i] - 1);
  235|       |
  236|  4.81k|      bad_input |= CT::Mask<size_t>(in_range) & ~incrementing;
  237|  4.81k|   }
  238|       |
  239|    137|   return bad_input.select(BS, pad_pos);
  240|    137|}

_ZN5Botan3TLS21check_tls_cbc_paddingEPKhm:
  264|    206|uint16_t check_tls_cbc_padding(const uint8_t record[], size_t record_len) {
  265|    206|   if(record_len == 0 || record_len > 0xFFFF) {
  ------------------
  |  Branch (265:7): [True: 0, False: 206]
  |  Branch (265:26): [True: 0, False: 206]
  ------------------
  266|      0|      return 0;
  267|      0|   }
  268|       |
  269|    206|   const uint16_t rec16 = static_cast<uint16_t>(record_len);
  270|       |
  271|       |   /*
  272|       |   * TLS v1.0 and up require all the padding bytes be the same value
  273|       |   * and allows up to 255 bytes.
  274|       |   */
  275|       |
  276|    206|   const uint16_t to_check = std::min<uint16_t>(256, static_cast<uint16_t>(record_len));
  277|    206|   const uint8_t pad_byte = record[record_len - 1];
  278|    206|   const uint16_t pad_bytes = 1 + pad_byte;
  279|       |
  280|    206|   auto pad_invalid = CT::Mask<uint16_t>::is_lt(rec16, pad_bytes);
  281|       |
  282|  15.9k|   for(uint16_t i = rec16 - to_check; i != rec16; ++i) {
  ------------------
  |  Branch (282:39): [True: 15.7k, False: 206]
  ------------------
  283|  15.7k|      const uint16_t offset = rec16 - i;
  284|  15.7k|      const auto in_pad_range = CT::Mask<uint16_t>::is_lte(offset, pad_bytes);
  285|  15.7k|      const auto pad_correct = CT::Mask<uint16_t>::is_equal(record[i], pad_byte);
  286|  15.7k|      pad_invalid |= in_pad_range & ~pad_correct;
  287|  15.7k|   }
  288|       |
  289|    206|   return pad_invalid.if_not_set_return(pad_bytes);
  290|    206|}

