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

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

_ZNK5Botan13PKCS7_Padding15valid_blocksizeEm:
  112|    307|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (112:64): [True: 284, False: 23]
  |  Branch (112:74): [True: 250, False: 34]
  ------------------
_ZNK5Botan17ANSI_X923_Padding15valid_blocksizeEm:
  126|    307|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (126:64): [True: 284, False: 23]
  |  Branch (126:74): [True: 250, False: 34]
  ------------------
_ZNK5Botan19OneAndZeros_Padding15valid_blocksizeEm:
  140|    341|      bool valid_blocksize(size_t bs) const override { return (bs > 2); }
_ZNK5Botan11ESP_Padding15valid_blocksizeEm:
  154|    307|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (154:64): [True: 284, False: 23]
  |  Branch (154:74): [True: 250, False: 34]
  ------------------

_ZN5Botan14scoped_cleanupIZNS_2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS7_EEEDaDpRKS7_EUlvE_EC2ESB_:
   26|    534|      explicit scoped_cleanup(FunT cleanup) : m_cleanup(std::move(cleanup)) {}
_ZN5Botan14scoped_cleanupIZNS_2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS7_EEEDaDpRKS7_EUlvE_EC2EOSC_:
   31|    534|      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:
   50|    534|      void disengage() noexcept { m_cleanup.reset(); }
_ZN5Botan14scoped_cleanupIZNS_2CT13scoped_poisonIJNSt3__14spanIKhLm18446744073709551615EEEEQaaaagtsZT_Li0Efraa10poisonableIT_Efraa12unpoisonableIS7_EEEDaDpRKS7_EUlvE_ED2Ev:
   41|  1.06k|      ~scoped_cleanup() {
   42|  1.06k|         if(m_cleanup.has_value()) {
  ------------------
  |  Branch (42:13): [True: 534, False: 534]
  ------------------
   43|    534|            (*m_cleanup)();  // NOLINT(bugprone-exception-escape) clang-tidy bug
   44|    534|         }
   45|  1.06k|      }

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

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

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

_ZNK5Botan28BlockCipherModePaddingMethod5unpadENSt3__14spanIKhLm18446744073709551615EEE:
   53|    534|size_t BlockCipherModePaddingMethod::unpad(std::span<const uint8_t> last_block) const {
   54|    534|   if(!valid_blocksize(last_block.size())) {
  ------------------
  |  Branch (54:7): [True: 0, False: 534]
  ------------------
   55|      0|      return last_block.size();
   56|      0|   }
   57|       |
   58|    534|   auto poison = CT::scoped_poison(last_block);
   59|    534|   return CT::driveby_unpoison(remove_padding(last_block));
   60|    534|}
_ZNK5Botan13PKCS7_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
   85|    125|size_t PKCS7_Padding::remove_padding(std::span<const uint8_t> input) const {
   86|    125|   const size_t BS = input.size();
   87|    125|   const uint8_t last_byte = input.back();
   88|       |
   89|       |   /*
   90|       |   The input should == the block size so if the last byte exceeds
   91|       |   that then the padding is certainly invalid
   92|       |   */
   93|    125|   auto bad_input = CT::Mask<size_t>::is_gt(last_byte, BS);
   94|       |
   95|    125|   const size_t pad_pos = BS - last_byte;
   96|       |
   97|  4.74k|   for(size_t i = 0; i != BS - 1; ++i) {
  ------------------
  |  Branch (97:22): [True: 4.62k, False: 125]
  ------------------
   98|       |      // Does this byte equal the expected pad byte?
   99|  4.62k|      const auto pad_eq = CT::Mask<size_t>::is_equal(input[i], last_byte);
  100|       |
  101|       |      // Ignore values that are not part of the padding
  102|  4.62k|      const auto in_range = CT::Mask<size_t>::is_gte(i, pad_pos);
  103|  4.62k|      bad_input |= in_range & (~pad_eq);
  104|  4.62k|   }
  105|       |
  106|    125|   return bad_input.select(BS, pad_pos);
  107|    125|}
_ZNK5Botan17ANSI_X923_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
  134|    125|size_t ANSI_X923_Padding::remove_padding(std::span<const uint8_t> input) const {
  135|    125|   const size_t BS = input.size();
  136|    125|   const size_t last_byte = input.back();
  137|       |
  138|    125|   auto bad_input = CT::Mask<size_t>::is_gt(last_byte, BS);
  139|       |
  140|    125|   const size_t pad_pos = BS - last_byte;
  141|       |
  142|  4.74k|   for(size_t i = 0; i != BS - 1; ++i) {
  ------------------
  |  Branch (142:22): [True: 4.62k, False: 125]
  ------------------
  143|       |      // Ignore values that are not part of the padding
  144|  4.62k|      const auto in_range = CT::Mask<size_t>::is_gte(i, pad_pos);
  145|  4.62k|      const auto pad_is_nonzero = CT::Mask<size_t>::expand(input[i]);
  146|  4.62k|      bad_input |= pad_is_nonzero & in_range;
  147|  4.62k|   }
  148|       |
  149|    125|   return bad_input.select(BS, pad_pos);
  150|    125|}
_ZNK5Botan19OneAndZeros_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
  173|    159|size_t OneAndZeros_Padding::remove_padding(std::span<const uint8_t> input) const {
  174|    159|   const size_t BS = input.size();
  175|    159|   auto bad_input = CT::Mask<uint8_t>::cleared();
  176|    159|   auto seen_0x80 = CT::Mask<uint8_t>::cleared();
  177|       |
  178|    159|   size_t pad_pos = BS - 1;
  179|       |
  180|   115k|   for(size_t i = BS; i != 0; --i) {
  ------------------
  |  Branch (180:23): [True: 115k, False: 159]
  ------------------
  181|   115k|      const auto is_0x80 = CT::Mask<uint8_t>::is_equal(input[i - 1], 0x80);
  182|   115k|      const auto is_zero = CT::Mask<uint8_t>::is_zero(input[i - 1]);
  183|       |
  184|   115k|      seen_0x80 |= is_0x80;
  185|   115k|      pad_pos -= seen_0x80.if_not_set_return(1);
  186|   115k|      bad_input |= ~seen_0x80 & ~is_zero;
  187|   115k|   }
  188|    159|   bad_input |= ~seen_0x80;
  189|       |
  190|    159|   return CT::Mask<size_t>::expand(bad_input).select(BS, pad_pos);
  191|    159|}
_ZNK5Botan11ESP_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
  218|    125|size_t ESP_Padding::remove_padding(std::span<const uint8_t> input) const {
  219|    125|   const size_t BS = input.size();
  220|    125|   const uint8_t last_byte = input.back();
  221|       |
  222|    125|   auto bad_input = CT::Mask<size_t>::is_zero(last_byte) | CT::Mask<size_t>::is_gt(last_byte, BS);
  223|       |
  224|    125|   const size_t pad_pos = BS - last_byte;
  225|  4.74k|   for(size_t i = BS - 1; i != 0; --i) {
  ------------------
  |  Branch (225:27): [True: 4.62k, False: 125]
  ------------------
  226|  4.62k|      const auto in_range = CT::Mask<size_t>::is_gt(i, pad_pos);
  227|  4.62k|      const auto incrementing = CT::Mask<size_t>::is_equal(input[i - 1], input[i] - 1);
  228|       |
  229|  4.62k|      bad_input |= CT::Mask<size_t>(in_range) & ~incrementing;
  230|  4.62k|   }
  231|       |
  232|    125|   return bad_input.select(BS, pad_pos);
  233|    125|}

_ZN5Botan3TLS21check_tls_cbc_paddingEPKhm:
  254|    182|uint16_t check_tls_cbc_padding(const uint8_t record[], size_t record_len) {
  255|    182|   if(record_len == 0 || record_len > 0xFFFF) {
  ------------------
  |  Branch (255:7): [True: 0, False: 182]
  |  Branch (255:26): [True: 0, False: 182]
  ------------------
  256|      0|      return 0;
  257|      0|   }
  258|       |
  259|    182|   const uint16_t rec16 = static_cast<uint16_t>(record_len);
  260|       |
  261|       |   /*
  262|       |   * TLS v1.0 and up require all the padding bytes be the same value
  263|       |   * and allows up to 255 bytes.
  264|       |   */
  265|       |
  266|    182|   const uint16_t to_check = std::min<uint16_t>(256, static_cast<uint16_t>(record_len));
  267|    182|   const uint8_t pad_byte = record[record_len - 1];
  268|    182|   const uint16_t pad_bytes = 1 + pad_byte;
  269|       |
  270|    182|   auto pad_invalid = CT::Mask<uint16_t>::is_lt(rec16, pad_bytes);
  271|       |
  272|  13.6k|   for(uint16_t i = rec16 - to_check; i != rec16; ++i) {
  ------------------
  |  Branch (272:39): [True: 13.4k, False: 182]
  ------------------
  273|  13.4k|      const uint16_t offset = rec16 - i;
  274|  13.4k|      const auto in_pad_range = CT::Mask<uint16_t>::is_lte(offset, pad_bytes);
  275|  13.4k|      const auto pad_correct = CT::Mask<uint16_t>::is_equal(record[i], pad_byte);
  276|  13.4k|      pad_invalid |= in_pad_range & ~pad_correct;
  277|  13.4k|   }
  278|       |
  279|    182|   return pad_invalid.if_not_set_return(pad_bytes);
  280|    182|}

