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

_ZN5Botan2CT6poisonIhEEvPKT_m:
   56|    595|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|    595|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  144|    595|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   64|    595|}
_ZN5Botan2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS6_EEEDaDpRKS6_:
  222|    595|[[nodiscard]] constexpr auto scoped_poison(const Ts&... xs) {
  223|    595|   auto scope = scoped_cleanup([&] { unpoison_all(xs...); });
  224|    595|   poison_all(xs...);
  225|    595|   return scope;
  226|    595|}
_ZN5Botan2CT10poison_allITpTkNS0_10poisonableEJNSt3__14spanIKhLm18446744073709551615EEEEQgtsZT_Li0EEEvDpRKT_:
  201|    595|constexpr void poison_all(const Ts&... ts) {
  202|    595|   (poison(ts), ...);
  203|    595|}
_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|    595|constexpr void poison(const R& r) {
  122|    595|   const std::span s{r};
  123|    595|   poison(s.data(), s.size());
  124|    595|}
_ZN5Botan2CT16driveby_unpoisonITkNS0_12unpoisonableEmEEDcOT_Qsr3stdE21is_rvalue_reference_vIDtfp_EE:
  245|    595|{
  246|    595|   unpoison(v);
  247|    595|   return std::forward<T>(v);
  248|    595|}
_ZN5Botan2CT8unpoisonITkNSt3__18integralEmEEvRKT_:
  112|    595|constexpr void unpoison(const T& p) {
  113|    595|   unpoison(&p, 1);
  114|    595|}
_ZN5Botan2CT8unpoisonImEEvPKT_m:
   67|    595|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|    595|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  144|    595|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   75|    595|}
_ZN5Botan2CT4MaskIhEC2Eh:
  637|   901k|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskIhE5valueEv:
  630|  1.26M|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZN5Botan2CT4MaskImE5is_gtEmm:
  458|  5.42k|      static constexpr Mask<T> is_gt(T x, T y) { return Mask<T>::is_lt(y, x); }
_ZN5Botan2CT4MaskImE5is_ltEmm:
  450|  15.4k|      static constexpr Mask<T> is_lt(T x, T y) {
  451|  15.4k|         T u = x ^ ((x ^ y) | ((x - y) ^ x));
  452|  15.4k|         return Mask<T>::expand_top_bit(u);
  453|  15.4k|      }
_ZN5Botan2CT4MaskImE14expand_top_bitEm:
  415|  15.4k|      static constexpr Mask<T> expand_top_bit(T v) { return Mask<T>(ct_expand_top_bit<T>(v)); }
_ZN5Botan2CT4MaskImEC2Em:
  637|  71.1k|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZN5Botan2CT4MaskImE8is_equalEmm:
  442|  10.0k|      static constexpr Mask<T> is_equal(T x, T y) {
  443|  10.0k|         const T diff = value_barrier(x) ^ value_barrier(y);
  444|  10.0k|         return Mask<T>::is_zero(diff);
  445|  10.0k|      }
_ZN5Botan2CT4MaskImE6is_gteEmm:
  468|  10.0k|      static constexpr Mask<T> is_gte(T x, T y) { return ~Mask<T>::is_lt(x, y); }
_ZNK5Botan2CT4MaskImEcoEv:
  533|  25.2k|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskImE5valueEv:
  630|  71.1k|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZNK5Botan2CT4MaskImE6selectEmm:
  548|    595|      constexpr T select(T x, T y) const { return choose(value(), x, y); }
_ZN5Botan2CT4MaskImE6expandEm:
  392|  5.00k|      static constexpr Mask<T> expand(T v) { return ~Mask<T>::is_zero(value_barrier<T>(v)); }
_ZN5Botan2CT4MaskIhE7clearedEv:
  387|    362|      static constexpr Mask<T> cleared() { return Mask<T>(0); }
_ZN5Botan2CT4MaskIhE8is_equalEhh:
  442|   180k|      static constexpr Mask<T> is_equal(T x, T y) {
  443|   180k|         const T diff = value_barrier(x) ^ value_barrier(y);
  444|   180k|         return Mask<T>::is_zero(diff);
  445|   180k|      }
_ZN5Botan2CT4MaskIhE7is_zeroEh:
  437|   360k|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZNK5Botan2CT4MaskIhE17if_not_set_returnEh:
  543|   180k|      constexpr T if_not_set_return(T x) const { return ~value() & x; }
_ZNK5Botan2CT4MaskIhEcoEv:
  533|   360k|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZN5Botan2CT4MaskImE6expandIhEES2_NS1_IT_EE:
  429|    181|      static constexpr Mask<T> expand(Mask<U> m) {
  430|    181|         static_assert(sizeof(U) < sizeof(T), "sizes ok");
  431|    181|         return ~Mask<T>::is_zero(m.value());
  432|    181|      }
_ZN5Botan2CT4MaskImE7is_zeroEm:
  437|  15.3k|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZN5Botan2CT8unpoisonIhEEvPKT_m:
   67|    595|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|    595|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  144|    595|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   75|    595|}
_ZZN5Botan2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS6_EEEDaDpRKS6_ENKUlvE_clEv:
  223|    595|   auto scope = scoped_cleanup([&] { unpoison_all(xs...); });
_ZN5Botan2CT12unpoison_allITpTkNS0_12unpoisonableEJNSt3__14spanIKhLm18446744073709551615EEEEQgtsZT_Li0EEEvDpRKT_:
  207|    595|constexpr void unpoison_all(const Ts&... ts) {
  208|    595|   (unpoison(ts), ...);
  209|    595|}
_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|    595|constexpr void unpoison(const R& r) {
  129|    595|   const std::span s{r};
  130|    595|   unpoison(s.data(), s.size());
  131|    595|}
_ZN5Botan2CTanENS0_4MaskImEES2_:
  518|  15.0k|      friend Mask<T> operator&(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() & y.value()); }
_ZN5Botan2CT4MaskImEoRES2_:
  510|  15.0k|      Mask<T>& operator|=(Mask<T> o) {
  511|  15.0k|         m_mask |= o.value();
  512|  15.0k|         return (*this);
  513|  15.0k|      }
_ZN5Botan2CT4MaskIhEoRES2_:
  510|   360k|      Mask<T>& operator|=(Mask<T> o) {
  511|   360k|         m_mask |= o.value();
  512|   360k|         return (*this);
  513|   360k|      }
_ZN5Botan2CTanENS0_4MaskIhEES2_:
  518|   180k|      friend Mask<T> operator&(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() & y.value()); }
_ZN5Botan2CTorENS0_4MaskImEES2_:
  528|    138|      friend Mask<T> operator|(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() | y.value()); }
_ZN5Botan2CT4MaskItE5is_ltEtt:
  450|  16.4k|      static constexpr Mask<T> is_lt(T x, T y) {
  451|  16.4k|         T u = x ^ ((x ^ y) | ((x - y) ^ x));
  452|  16.4k|         return Mask<T>::expand_top_bit(u);
  453|  16.4k|      }
_ZN5Botan2CT4MaskItE14expand_top_bitEt:
  415|  16.4k|      static constexpr Mask<T> expand_top_bit(T v) { return Mask<T>(ct_expand_top_bit<T>(v)); }
_ZN5Botan2CT4MaskItEC2Et:
  637|  81.2k|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZN5Botan2CT4MaskItE6is_lteEtt:
  463|  16.2k|      static constexpr Mask<T> is_lte(T x, T y) { return ~Mask<T>::is_gt(x, y); }
_ZN5Botan2CT4MaskItE5is_gtEtt:
  458|  16.2k|      static constexpr Mask<T> is_gt(T x, T y) { return Mask<T>::is_lt(y, x); }
_ZN5Botan2CT4MaskItE8is_equalEtt:
  442|  16.2k|      static constexpr Mask<T> is_equal(T x, T y) {
  443|  16.2k|         const T diff = value_barrier(x) ^ value_barrier(y);
  444|  16.2k|         return Mask<T>::is_zero(diff);
  445|  16.2k|      }
_ZN5Botan2CT4MaskItE7is_zeroEt:
  437|  16.2k|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZNK5Botan2CT4MaskItEcoEv:
  533|  32.4k|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskItE5valueEv:
  630|  81.2k|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZNK5Botan2CT4MaskItE17if_not_set_returnEt:
  543|    209|      constexpr T if_not_set_return(T x) const { return ~value() & x; }
_ZN5Botan2CTanENS0_4MaskItEES2_:
  518|  16.2k|      friend Mask<T> operator&(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() & y.value()); }
_ZN5Botan2CT4MaskItEoRES2_:
  510|  16.2k|      Mask<T>& operator|=(Mask<T> o) {
  511|  16.2k|         m_mask |= o.value();
  512|  16.2k|         return (*this);
  513|  16.2k|      }

_ZNK5Botan13PKCS7_Padding15valid_blocksizeEm:
  110|    347|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (110:64): [True: 319, False: 28]
  |  Branch (110:74): [True: 276, False: 43]
  ------------------
_ZNK5Botan17ANSI_X923_Padding15valid_blocksizeEm:
  124|    347|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (124:64): [True: 319, False: 28]
  |  Branch (124:74): [True: 276, False: 43]
  ------------------
_ZNK5Botan19OneAndZeros_Padding15valid_blocksizeEm:
  138|    390|      bool valid_blocksize(size_t bs) const override { return (bs > 2); }
_ZNK5Botan11ESP_Padding15valid_blocksizeEm:
  152|    347|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (152:64): [True: 319, False: 28]
  |  Branch (152:74): [True: 276, False: 43]
  ------------------

_ZN5Botan14scoped_cleanupIZNS_2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS7_EEEDaDpRKS7_EUlvE_EC2ESB_:
   26|    595|      explicit scoped_cleanup(FunT cleanup) : m_cleanup(std::move(cleanup)) {}
_ZN5Botan14scoped_cleanupIZNS_2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS7_EEEDaDpRKS7_EUlvE_EC2EOSC_:
   32|    595|      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|    595|      void disengage() noexcept { m_cleanup.reset(); }
_ZN5Botan14scoped_cleanupIZNS_2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS7_EEEDaDpRKS7_EUlvE_ED2Ev:
   34|  1.19k|      ~scoped_cleanup() {
   35|  1.19k|         if(m_cleanup.has_value()) {
  ------------------
  |  Branch (35:13): [True: 595, False: 595]
  ------------------
   36|    595|            (*m_cleanup)();  // NOLINT(bugprone-exception-escape) clang-tidy bug
   37|    595|         }
   38|  1.19k|      }

_ZN5Botan2CT13value_barrierITkNSt3__117unsigned_integralEhQntsr3stdE7same_asIbT_EEES3_S3_:
   43|  2.34M|constexpr inline T value_barrier(T x) {
   44|  2.34M|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (44:7): [Folded, False: 2.34M]
  ------------------
   45|      0|      return x;
   46|  2.34M|   } else {
   47|  2.34M|#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.34M|      asm("" : "+r"(x) : /* no input */);  // NOLINT(*-no-assembler)
   56|  2.34M|      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.34M|   }
   64|  2.34M|}
_ZN5Botan2CT13value_barrierITkNSt3__117unsigned_integralEmQntsr3stdE7same_asIbT_EEES3_S3_:
   43|   142k|constexpr inline T value_barrier(T x) {
   44|   142k|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (44:7): [Folded, False: 142k]
  ------------------
   45|      0|      return x;
   46|   142k|   } else {
   47|   142k|#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|   142k|      asm("" : "+r"(x) : /* no input */);  // NOLINT(*-no-assembler)
   56|   142k|      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|   142k|   }
   64|   142k|}
_ZN5Botan2CT13value_barrierITkNSt3__117unsigned_integralEtQntsr3stdE7same_asIbT_EEES3_S3_:
   43|   162k|constexpr inline T value_barrier(T x) {
   44|   162k|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (44:7): [Folded, False: 162k]
  ------------------
   45|      0|      return x;
   46|   162k|   } else {
   47|   162k|#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|   162k|      asm("" : "+r"(x) : /* no input */);  // NOLINT(*-no-assembler)
   56|   162k|      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|   162k|   }
   64|   162k|}

_ZN5Botan13ignore_paramsIJPKmmEEEvDpRKT_:
  142|    595|constexpr void ignore_params([[maybe_unused]] const T&... args) {}
_ZN5Botan13ignore_paramsIJPKhmEEEvDpRKT_:
  142|  1.19k|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|    219|extern "C" int LLVMFuzzerTestOneInput(const uint8_t in[], size_t len) {
   40|    219|   if(len <= max_fuzzer_input_size) {
  ------------------
  |  Branch (40:7): [True: 209, False: 10]
  ------------------
   41|    209|      try {
   42|    209|         fuzz(std::span<const uint8_t>(in, len));
   43|    209|      } 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|    209|   }
   51|    219|   return 0;
   52|    219|}

_Z4fuzzNSt3__14spanIKhLm18446744073709551615EEE:
  132|    209|void fuzz(std::span<const uint8_t> in) {
  133|    209|   static const Botan::PKCS7_Padding pkcs7;
  134|    209|   static const Botan::ANSI_X923_Padding x923;
  135|    209|   static const Botan::OneAndZeros_Padding oneandzero;
  136|    209|   static const Botan::ESP_Padding esp;
  137|       |
  138|    209|   const size_t len = in.size();
  139|       |
  140|    209|   if(pkcs7.valid_blocksize(len)) {
  ------------------
  |  Branch (140:7): [True: 138, False: 71]
  ------------------
  141|    138|      const size_t ct_pkcs7 = pkcs7.unpad(in);
  142|    138|      const size_t ref_pkcs7 = ref_pkcs7_unpad(in);
  143|    138|      FUZZER_ASSERT_EQUAL(ct_pkcs7, ref_pkcs7);
  ------------------
  |  |   79|    138|   do {                                                                                      \
  |  |   80|    138|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 138]
  |  |  ------------------
  |  |   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|    138|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 138]
  |  |  ------------------
  ------------------
  144|    138|   }
  145|       |
  146|    209|   if(x923.valid_blocksize(len)) {
  ------------------
  |  Branch (146:7): [True: 138, False: 71]
  ------------------
  147|    138|      const size_t ct_x923 = x923.unpad(in);
  148|    138|      const size_t ref_x923 = ref_x923_unpad(in);
  149|    138|      FUZZER_ASSERT_EQUAL(ct_x923, ref_x923);
  ------------------
  |  |   79|    138|   do {                                                                                      \
  |  |   80|    138|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 138]
  |  |  ------------------
  |  |   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|    138|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 138]
  |  |  ------------------
  ------------------
  150|    138|   }
  151|       |
  152|    209|   if(oneandzero.valid_blocksize(len)) {
  ------------------
  |  Branch (152:7): [True: 181, False: 28]
  ------------------
  153|    181|      const size_t ct_oneandzero = oneandzero.unpad(in);
  154|    181|      const size_t ref_oneandzero = ref_oneandzero_unpad(in);
  155|    181|      FUZZER_ASSERT_EQUAL(ct_oneandzero, ref_oneandzero);
  ------------------
  |  |   79|    181|   do {                                                                                      \
  |  |   80|    181|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 181]
  |  |  ------------------
  |  |   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|    181|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 181]
  |  |  ------------------
  ------------------
  156|    181|   }
  157|       |
  158|    209|   if(esp.valid_blocksize(len)) {
  ------------------
  |  Branch (158:7): [True: 138, False: 71]
  ------------------
  159|    138|      const size_t ct_esp = esp.unpad(in);
  160|    138|      const size_t ref_esp = ref_esp_unpad(in);
  161|    138|      FUZZER_ASSERT_EQUAL(ct_esp, ref_esp);
  ------------------
  |  |   79|    138|   do {                                                                                      \
  |  |   80|    138|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 138]
  |  |  ------------------
  |  |   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|    138|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 138]
  |  |  ------------------
  ------------------
  162|    138|   }
  163|       |
  164|    209|   const uint16_t ct_cbc = Botan::TLS::check_tls_cbc_padding(in.data(), len);
  165|    209|   const uint16_t ref_cbc = ref_tls_cbc_unpad(in);
  166|    209|   FUZZER_ASSERT_EQUAL(ct_cbc, ref_cbc);
  ------------------
  |  |   79|    209|   do {                                                                                      \
  |  |   80|    209|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 209]
  |  |  ------------------
  |  |   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|    209|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 209]
  |  |  ------------------
  ------------------
  167|    209|}
mode_padding.cpp:_ZN12_GLOBAL__N_115ref_pkcs7_unpadENSt3__14spanIKhLm18446744073709551615EEE:
   14|    138|size_t ref_pkcs7_unpad(std::span<const uint8_t> in) {
   15|    138|   if(in.size() <= 2) {
  ------------------
  |  Branch (15:7): [True: 0, False: 138]
  ------------------
   16|      0|      return in.size();
   17|      0|   }
   18|    138|   const size_t len = in.size();
   19|       |
   20|    138|   const size_t padding_length = in[len - 1];
   21|       |
   22|    138|   if(padding_length == 0 || padding_length > len) {
  ------------------
  |  Branch (22:7): [True: 25, False: 113]
  |  Branch (22:30): [True: 26, False: 87]
  ------------------
   23|     51|      return len;
   24|     51|   }
   25|       |
   26|     87|   const size_t padding_start = len - padding_length;
   27|       |
   28|    571|   for(size_t i = padding_start; i != len; ++i) {
  ------------------
  |  Branch (28:34): [True: 546, False: 25]
  ------------------
   29|    546|      if(in[i] != padding_length) {
  ------------------
  |  Branch (29:10): [True: 62, False: 484]
  ------------------
   30|     62|         return len;
   31|     62|      }
   32|    546|   }
   33|       |
   34|     25|   return len - padding_length;
   35|     87|}
mode_padding.cpp:_ZN12_GLOBAL__N_114ref_x923_unpadENSt3__14spanIKhLm18446744073709551615EEE:
   37|    138|size_t ref_x923_unpad(std::span<const uint8_t> in) {
   38|    138|   const size_t len = in.size();
   39|    138|   if(len <= 2) {
  ------------------
  |  Branch (39:7): [True: 0, False: 138]
  ------------------
   40|      0|      return len;
   41|      0|   }
   42|       |
   43|    138|   const size_t padding_length = in[len - 1];
   44|       |
   45|    138|   if(padding_length == 0 || padding_length > len) {
  ------------------
  |  Branch (45:7): [True: 25, False: 113]
  |  Branch (45:30): [True: 26, False: 87]
  ------------------
   46|     51|      return len;
   47|     51|   }
   48|     87|   const size_t padding_start = len - padding_length;
   49|       |
   50|    405|   for(size_t i = padding_start; i != len - 1; ++i) {
  ------------------
  |  Branch (50:34): [True: 393, False: 12]
  ------------------
   51|    393|      if(in[i] != 0) {
  ------------------
  |  Branch (51:10): [True: 75, False: 318]
  ------------------
   52|     75|         return len;
   53|     75|      }
   54|    393|   }
   55|       |
   56|     12|   return len - padding_length;
   57|     87|}
mode_padding.cpp:_ZN12_GLOBAL__N_120ref_oneandzero_unpadENSt3__14spanIKhLm18446744073709551615EEE:
   59|    181|size_t ref_oneandzero_unpad(std::span<const uint8_t> in) {
   60|    181|   const size_t len = in.size();
   61|    181|   if(len <= 2) {
  ------------------
  |  Branch (61:7): [True: 0, False: 181]
  ------------------
   62|      0|      return len;
   63|      0|   }
   64|       |
   65|    181|   size_t idx = len - 1;
   66|       |
   67|  1.12k|   for(;;) {
   68|  1.12k|      if(in[idx] == 0) {
  ------------------
  |  Branch (68:10): [True: 943, False: 178]
  ------------------
   69|    943|         if(idx == 0) {
  ------------------
  |  Branch (69:13): [True: 3, False: 940]
  ------------------
   70|      3|            return len;
   71|      3|         }
   72|    940|         idx -= 1;
   73|    940|         continue;
   74|    943|      } else if(in[idx] == 0x80) {
  ------------------
  |  Branch (74:17): [True: 4, False: 174]
  ------------------
   75|      4|         return idx;
   76|    174|      } else {
   77|    174|         return len;
   78|    174|      }
   79|  1.12k|   }
   80|       |
   81|      0|   return len;
   82|    181|}
mode_padding.cpp:_ZN12_GLOBAL__N_113ref_esp_unpadENSt3__14spanIKhLm18446744073709551615EEE:
   84|    138|size_t ref_esp_unpad(std::span<const uint8_t> in) {
   85|    138|   const size_t len = in.size();
   86|    138|   if(len <= 2) {
  ------------------
  |  Branch (86:7): [True: 0, False: 138]
  ------------------
   87|      0|      return len;
   88|      0|   }
   89|       |
   90|    138|   const size_t padding_bytes = in[len - 1];
   91|       |
   92|    138|   if(padding_bytes == 0 || padding_bytes > len) {
  ------------------
  |  Branch (92:7): [True: 25, False: 113]
  |  Branch (92:29): [True: 26, False: 87]
  ------------------
   93|     51|      return len;
   94|     51|   }
   95|       |
   96|     87|   const size_t padding_start = len - padding_bytes;
   97|    243|   for(size_t i = padding_start; i != len; ++i) {
  ------------------
  |  Branch (97:34): [True: 226, False: 17]
  ------------------
   98|    226|      if(in[i] != (i - padding_start + 1)) {
  ------------------
  |  Branch (98:10): [True: 70, False: 156]
  ------------------
   99|     70|         return len;
  100|     70|      }
  101|    226|   }
  102|       |
  103|     17|   return len - padding_bytes;
  104|     87|}
mode_padding.cpp:_ZN12_GLOBAL__N_117ref_tls_cbc_unpadENSt3__14spanIKhLm18446744073709551615EEE:
  106|    209|uint16_t ref_tls_cbc_unpad(std::span<const uint8_t> in) {
  107|    209|   const size_t len = in.size();
  108|    209|   if(len == 0) {
  ------------------
  |  Branch (108:7): [True: 0, False: 209]
  ------------------
  109|      0|      return 0;
  110|      0|   }
  111|       |
  112|    209|   const size_t padding_length = in[(len - 1)];
  113|       |
  114|    209|   if(padding_length >= len) {
  ------------------
  |  Branch (114:7): [True: 77, False: 132]
  ------------------
  115|     77|      return 0;
  116|     77|   }
  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|    907|   for(size_t i = 0; i != 1 + padding_length; ++i) {
  ------------------
  |  Branch (122:22): [True: 861, False: 46]
  ------------------
  123|    861|      if(in[(len - i - 1)] != padding_length) {
  ------------------
  |  Branch (123:10): [True: 86, False: 775]
  ------------------
  124|     86|         return 0;
  125|     86|      }
  126|    861|   }
  127|     46|   return padding_length + 1;
  128|    132|}

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

_ZN5Botan3TLS21check_tls_cbc_paddingEPKhm:
  264|    209|uint16_t check_tls_cbc_padding(const uint8_t record[], size_t record_len) {
  265|    209|   if(record_len == 0 || record_len > 0xFFFF) {
  ------------------
  |  Branch (265:7): [True: 0, False: 209]
  |  Branch (265:26): [True: 0, False: 209]
  ------------------
  266|      0|      return 0;
  267|      0|   }
  268|       |
  269|    209|   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|    209|   const uint16_t to_check = std::min<uint16_t>(256, static_cast<uint16_t>(record_len));
  277|    209|   const uint8_t pad_byte = record[record_len - 1];
  278|    209|   const uint16_t pad_bytes = 1 + pad_byte;
  279|       |
  280|    209|   auto pad_invalid = CT::Mask<uint16_t>::is_lt(rec16, pad_bytes);
  281|       |
  282|  16.4k|   for(uint16_t i = rec16 - to_check; i != rec16; ++i) {
  ------------------
  |  Branch (282:39): [True: 16.2k, False: 209]
  ------------------
  283|  16.2k|      const uint16_t offset = rec16 - i;
  284|  16.2k|      const auto in_pad_range = CT::Mask<uint16_t>::is_lte(offset, pad_bytes);
  285|  16.2k|      const auto pad_correct = CT::Mask<uint16_t>::is_equal(record[i], pad_byte);
  286|  16.2k|      pad_invalid |= in_pad_range & ~pad_correct;
  287|  16.2k|   }
  288|       |
  289|    209|   return pad_invalid.if_not_set_return(pad_bytes);
  290|    209|}

