_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|  29.3k|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|  29.3k|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|  29.3k|   return static_cast<T>(0) - top;
   31|  29.3k|}
_ZN5Botan6chooseITkNSt3__117unsigned_integralEmEET_S2_S2_S2_:
  216|    579|BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b) {
  217|       |   //return (mask & a) | (~mask & b);
  218|    579|   return (b ^ (mask & (a ^ b)));
  219|    579|}
_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.6k|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|  14.6k|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|  14.6k|}
_ZN5Botan17ct_expand_top_bitITkNSt3__117unsigned_integralEtEET_S2_:
   28|  28.0k|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|  28.0k|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|  28.0k|   return static_cast<T>(0) - top;
   31|  28.0k|}
_ZN5Botan10ct_is_zeroITkNSt3__117unsigned_integralEtEET_S2_:
   37|  13.9k|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|  13.9k|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|  13.9k|}

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

_ZNK5Botan13PKCS7_Padding15valid_blocksizeEm:
  112|    334|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (112:64): [True: 307, False: 27]
  |  Branch (112:74): [True: 272, False: 35]
  ------------------
_ZNK5Botan17ANSI_X923_Padding15valid_blocksizeEm:
  126|    334|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (126:64): [True: 307, False: 27]
  |  Branch (126:74): [True: 272, False: 35]
  ------------------
_ZNK5Botan19OneAndZeros_Padding15valid_blocksizeEm:
  140|    369|      bool valid_blocksize(size_t bs) const override { return (bs > 2); }
_ZNK5Botan11ESP_Padding15valid_blocksizeEm:
  154|    334|      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
  ------------------
  |  Branch (154:64): [True: 307, False: 27]
  |  Branch (154:74): [True: 272, False: 35]
  ------------------

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

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

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

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

_ZNK5Botan28BlockCipherModePaddingMethod5unpadENSt3__14spanIKhLm18446744073709551615EEE:
   53|    579|size_t BlockCipherModePaddingMethod::unpad(std::span<const uint8_t> last_block) const {
   54|    579|   if(!valid_blocksize(last_block.size())) {
  ------------------
  |  Branch (54:7): [True: 0, False: 579]
  ------------------
   55|      0|      return last_block.size();
   56|      0|   }
   57|       |
   58|    579|   auto poison = CT::scoped_poison(last_block);
   59|    579|   return CT::driveby_unpoison(remove_padding(last_block));
   60|    579|}
_ZNK5Botan13PKCS7_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
   85|    136|size_t PKCS7_Padding::remove_padding(std::span<const uint8_t> input) const {
   86|    136|   const size_t BS = input.size();
   87|    136|   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|    136|   auto bad_input = CT::Mask<size_t>::is_gt(last_byte, BS);
   94|       |
   95|    136|   const size_t pad_pos = BS - last_byte;
   96|       |
   97|  4.90k|   for(size_t i = 0; i != BS - 1; ++i) {
  ------------------
  |  Branch (97:22): [True: 4.77k, False: 136]
  ------------------
   98|       |      // Does this byte equal the expected pad byte?
   99|  4.77k|      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.77k|      const auto in_range = CT::Mask<size_t>::is_gte(i, pad_pos);
  103|  4.77k|      bad_input |= in_range & (~pad_eq);
  104|  4.77k|   }
  105|       |
  106|    136|   return bad_input.select(BS, pad_pos);
  107|    136|}
_ZNK5Botan17ANSI_X923_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
  134|    136|size_t ANSI_X923_Padding::remove_padding(std::span<const uint8_t> input) const {
  135|    136|   const size_t BS = input.size();
  136|    136|   const size_t last_byte = input.back();
  137|       |
  138|    136|   auto bad_input = CT::Mask<size_t>::is_gt(last_byte, BS);
  139|       |
  140|    136|   const size_t pad_pos = BS - last_byte;
  141|       |
  142|  4.90k|   for(size_t i = 0; i != BS - 1; ++i) {
  ------------------
  |  Branch (142:22): [True: 4.77k, False: 136]
  ------------------
  143|       |      // Ignore values that are not part of the padding
  144|  4.77k|      const auto in_range = CT::Mask<size_t>::is_gte(i, pad_pos);
  145|  4.77k|      const auto pad_is_nonzero = CT::Mask<size_t>::expand(input[i]);
  146|  4.77k|      bad_input |= pad_is_nonzero & in_range;
  147|  4.77k|   }
  148|       |
  149|    136|   return bad_input.select(BS, pad_pos);
  150|    136|}
_ZNK5Botan19OneAndZeros_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
  173|    171|size_t OneAndZeros_Padding::remove_padding(std::span<const uint8_t> input) const {
  174|    171|   const size_t BS = input.size();
  175|    171|   auto bad_input = CT::Mask<uint8_t>::cleared();
  176|    171|   auto seen_0x80 = CT::Mask<uint8_t>::cleared();
  177|       |
  178|    171|   size_t pad_pos = BS - 1;
  179|       |
  180|   115k|   for(size_t i = BS; i != 0; --i) {
  ------------------
  |  Branch (180:23): [True: 115k, False: 171]
  ------------------
  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|    171|   bad_input |= ~seen_0x80;
  189|       |
  190|    171|   return CT::Mask<size_t>::expand(bad_input).select(BS, pad_pos);
  191|    171|}
_ZNK5Botan11ESP_Padding14remove_paddingENSt3__14spanIKhLm18446744073709551615EEE:
  218|    136|size_t ESP_Padding::remove_padding(std::span<const uint8_t> input) const {
  219|    136|   const size_t BS = input.size();
  220|    136|   const uint8_t last_byte = input.back();
  221|       |
  222|    136|   auto bad_input = CT::Mask<size_t>::is_zero(last_byte) | CT::Mask<size_t>::is_gt(last_byte, BS);
  223|       |
  224|    136|   const size_t pad_pos = BS - last_byte;
  225|  4.90k|   for(size_t i = BS - 1; i != 0; --i) {
  ------------------
  |  Branch (225:27): [True: 4.77k, False: 136]
  ------------------
  226|  4.77k|      const auto in_range = CT::Mask<size_t>::is_gt(i, pad_pos);
  227|  4.77k|      const auto incrementing = CT::Mask<size_t>::is_equal(input[i - 1], input[i] - 1);
  228|       |
  229|  4.77k|      bad_input |= CT::Mask<size_t>(in_range) & ~incrementing;
  230|  4.77k|   }
  231|       |
  232|    136|   return bad_input.select(BS, pad_pos);
  233|    136|}

_ZN5Botan3TLS21check_tls_cbc_paddingEPKhm:
  254|    198|uint16_t check_tls_cbc_padding(const uint8_t record[], size_t record_len) {
  255|    198|   if(record_len == 0 || record_len > 0xFFFF) {
  ------------------
  |  Branch (255:7): [True: 0, False: 198]
  |  Branch (255:26): [True: 0, False: 198]
  ------------------
  256|      0|      return 0;
  257|      0|   }
  258|       |
  259|    198|   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|    198|   const uint16_t to_check = std::min<uint16_t>(256, static_cast<uint16_t>(record_len));
  267|    198|   const uint8_t pad_byte = record[record_len - 1];
  268|    198|   const uint16_t pad_bytes = 1 + pad_byte;
  269|       |
  270|    198|   auto pad_invalid = CT::Mask<uint16_t>::is_lt(rec16, pad_bytes);
  271|       |
  272|  14.1k|   for(uint16_t i = rec16 - to_check; i != rec16; ++i) {
  ------------------
  |  Branch (272:39): [True: 13.9k, False: 198]
  ------------------
  273|  13.9k|      const uint16_t offset = rec16 - i;
  274|  13.9k|      const auto in_pad_range = CT::Mask<uint16_t>::is_lte(offset, pad_bytes);
  275|  13.9k|      const auto pad_correct = CT::Mask<uint16_t>::is_equal(record[i], pad_byte);
  276|  13.9k|      pad_invalid |= in_pad_range & ~pad_correct;
  277|  13.9k|   }
  278|       |
  279|    198|   return pad_invalid.if_not_set_return(pad_bytes);
  280|    198|}

