diff options
author | Jack Lloyd <[email protected]> | 2016-10-30 23:39:21 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-10-30 23:39:21 -0400 |
commit | 6582fe8638ab6c37551691a6a0196b22977a6e2e (patch) | |
tree | 152f0e76e76349f916b17c900bb7b39b5fcecb8f /src/extra_tests/fuzzers/jigs | |
parent | 76a0cff3b0200660ef678bbdaf3762e45c27bccd (diff) |
Import fuzzer drivers
Originally from https://github.com/randombit/botan-fuzzers but
merging to the main tree (without the corpus files, since I suspect
the corpus files in that repo are not useful anymore)
Adds --unsafe-fuzzer-mode which can be used to selectively disable
cryptographic checks which get in the way of fuzzer testing. This
setting is reflected in build.h and in the version string. Right
now it doesn't actually disable anything.
Diffstat (limited to 'src/extra_tests/fuzzers/jigs')
23 files changed, 952 insertions, 0 deletions
diff --git a/src/extra_tests/fuzzers/jigs/bn_sqr.cpp b/src/extra_tests/fuzzers/jigs/bn_sqr.cpp new file mode 100644 index 000000000..2bc5ebe33 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/bn_sqr.cpp @@ -0,0 +1,21 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "driver.h" + +#include <botan/bigint.h> +#include <botan/numthry.h> + +void fuzz(const uint8_t in[], size_t len) + { + Botan::BigInt x = Botan::BigInt::decode(in, len); + + Botan::BigInt x_sqr = square(x); + Botan::BigInt x_mul = x * x; + + FUZZER_ASSERT_EQUAL(x_sqr, x_mul); + } + diff --git a/src/extra_tests/fuzzers/jigs/cert.cpp b/src/extra_tests/fuzzers/jigs/cert.cpp new file mode 100644 index 000000000..2c13551e2 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/cert.cpp @@ -0,0 +1,18 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" + +#include <botan/x509cert.h> + +void fuzz(const uint8_t in[], size_t len) + { + try + { + DataSource_Memory input(in, len); + X509_Certificate cert(input); + } + catch(Botan::Exception& e) { } + } diff --git a/src/extra_tests/fuzzers/jigs/crl.cpp b/src/extra_tests/fuzzers/jigs/crl.cpp new file mode 100644 index 000000000..be61ae131 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/crl.cpp @@ -0,0 +1,18 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" + +#include <botan/x509_crl.h> + +void fuzz(const uint8_t in[], size_t len) + { + try + { + DataSource_Memory input(in, len); + X509_CRL crl(input); + } + catch(Botan::Exception& e) { } + } diff --git a/src/extra_tests/fuzzers/jigs/divide.cpp b/src/extra_tests/fuzzers/jigs/divide.cpp new file mode 100644 index 000000000..fba68b9a6 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/divide.cpp @@ -0,0 +1,26 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" +#include <botan/divide.h> + +void fuzz(const uint8_t in[], size_t len) + { + const BigInt x = BigInt::decode(in, len / 2); + const BigInt y = BigInt::decode(in + len / 2, len / 2); + + if(y == 0) + return; + + BigInt q, r; + Botan::divide(x, y, q, r); + + FUZZER_ASSERT_TRUE(r < y); + + BigInt z = q*y + r; + + FUZZER_ASSERT_EQUAL(z, x); + } + diff --git a/src/extra_tests/fuzzers/jigs/driver.h b/src/extra_tests/fuzzers/jigs/driver.h new file mode 100644 index 000000000..530cc80b7 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/driver.h @@ -0,0 +1,87 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef FUZZER_DRIVER_H_ +#define FUZZER_DRIVER_H_ + +#include <stdint.h> +#include <iostream> +#include <vector> +#include <stdlib.h> // for setenv +#include <botan/exceptn.h> + +using namespace Botan; + +void fuzz(const uint8_t in[], size_t len); + +void fuzzer_init() + { + /* + * This disables the mlock pool, as overwrites within the pool are + * opaque to ASan or other instrumentation. + */ + ::setenv("BOTAN_MLOCK_POOL_SIZE", "0", 1); + } + +#if defined(USE_LLVM_FUZZER) + +// Called by main() in libFuzzer +extern "C" int LLVMFuzzerTestOneInput(const uint8_t in[], size_t len) + { + fuzz(in, len); + return 0; + } + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + fuzzer_init(); + return 0; +} + +#else + +// Read stdin for AFL + +int main(int argc, char* argv[]) + { + const size_t max_read = 4096; + + fuzzer_init(); + +#if defined(__AFL_LOOP) + while(__AFL_LOOP(1000)) +#endif + { + std::vector<uint8_t> buf(max_read); + std::cin.read((char*)buf.data(), buf.size()); + size_t got = std::cin.gcount(); + + buf.resize(got); + buf.shrink_to_fit(); + + fuzz(buf.data(), got); + } + } + +#endif + +#endif + +// Some helpers for the fuzzer jigs + +#define FUZZER_ASSERT_EQUAL(x, y) do { \ + if(x != y) { \ + std::cerr << #x << " = " << x << " !=\n" << #y << " = " << y \ + << " at " << __LINE__ << ":" << __FILE__ << std::endl; \ + abort(); \ +} } while(0) + +#define FUZZER_ASSERT_TRUE(e) \ + do { \ + if(!(e)) { \ + std::cerr << "Expression " << #e << " was false at " \ + << __LINE__ << ":" << __FILE__ << std::endl; \ + abort(); \ + } } while(0) diff --git a/src/extra_tests/fuzzers/jigs/ecc_bp256.cpp b/src/extra_tests/fuzzers/jigs/ecc_bp256.cpp new file mode 100644 index 000000000..5b979b03f --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/ecc_bp256.cpp @@ -0,0 +1,13 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" +#include "ecc_helper.h" + +void fuzz(const uint8_t in[], size_t len) + { + static EC_Group bp256("brainpool256r1"); + return check_ecc_math(bp256, in, len); + } diff --git a/src/extra_tests/fuzzers/jigs/ecc_helper.h b/src/extra_tests/fuzzers/jigs/ecc_helper.h new file mode 100644 index 000000000..9848e6a9e --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/ecc_helper.h @@ -0,0 +1,74 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#ifndef ECC_HELPERS_H__ +#define ECC_HELPERS_H__ + +#include "driver.h" +#include <botan/curve_gfp.h> +#include <botan/ec_group.h> +#include <botan/reducer.h> +#include <botan/system_rng.h> + +void check_redc(std::function<void (BigInt&, secure_vector<word>&)> redc_fn, + const Modular_Reducer& redc, + const BigInt& prime, + const BigInt& x) + { + const Botan::BigInt v1 = x % prime; + const Botan::BigInt v2 = redc.reduce(x); + + Botan::secure_vector<Botan::word> ws; + Botan::BigInt v3 = x; + redc_fn(v3, ws); + + FUZZER_ASSERT_EQUAL(v1, v2); + FUZZER_ASSERT_EQUAL(v2, v3); + } + +inline std::ostream& operator<<(std::ostream& o, const PointGFp& point) + { + o << point.get_affine_x() << "," << point.get_affine_y(); + return o; + } + +void check_ecc_math(const EC_Group& group, const uint8_t in[], size_t len) + { + const size_t hlen = len / 2; + const BigInt a = BigInt::decode(in, hlen); + const BigInt b = BigInt::decode(in + hlen, len - hlen); + + const Botan::PointGFp& base_point = group.get_base_point(); + const Botan::BigInt& group_order = group.get_order(); + + const Botan::BigInt c = a + b; + + const Botan::PointGFp P = base_point * a; + const Botan::PointGFp Q = base_point * b; + const Botan::PointGFp R = base_point * c; + + const Botan::PointGFp A1 = P + Q; + const Botan::PointGFp A2 = Q + P; + + if(a == 31337 && b == 31337) + abort(); + + FUZZER_ASSERT_EQUAL(A1, R); + FUZZER_ASSERT_EQUAL(A2, R); + + Botan::Blinded_Point_Multiply blind(base_point, group_order, 4); + + const Botan::PointGFp P1 = blind.blinded_multiply(a, system_rng()); + const Botan::PointGFp Q1 = blind.blinded_multiply(b, system_rng()); + const Botan::PointGFp R1 = blind.blinded_multiply(c, system_rng()); + + const Botan::PointGFp S1 = P1 + Q1; + const Botan::PointGFp S2 = Q1 + P1; + + FUZZER_ASSERT_EQUAL(S1, R1); + FUZZER_ASSERT_EQUAL(S2, R1); + } + +#endif diff --git a/src/extra_tests/fuzzers/jigs/ecc_p256.cpp b/src/extra_tests/fuzzers/jigs/ecc_p256.cpp new file mode 100644 index 000000000..429925ba1 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/ecc_p256.cpp @@ -0,0 +1,13 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" +#include "ecc_helper.h" + +void fuzz(const uint8_t in[], size_t len) + { + static EC_Group p256("secp256r1"); + return check_ecc_math(p256, in, len); + } diff --git a/src/extra_tests/fuzzers/jigs/ecc_p384.cpp b/src/extra_tests/fuzzers/jigs/ecc_p384.cpp new file mode 100644 index 000000000..0441b6dcf --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/ecc_p384.cpp @@ -0,0 +1,13 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" +#include "ecc_helper.h" + +void fuzz(const uint8_t in[], size_t len) + { + static EC_Group p384("secp384r1"); + return check_ecc_math(p384, in, len); + } diff --git a/src/extra_tests/fuzzers/jigs/ecc_p521.cpp b/src/extra_tests/fuzzers/jigs/ecc_p521.cpp new file mode 100644 index 000000000..cc998137c --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/ecc_p521.cpp @@ -0,0 +1,13 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" +#include "ecc_helper.h" + +void fuzz(const uint8_t in[], size_t len) + { + static EC_Group p521("secp521r1"); + return check_ecc_math(p521, in, len); + } diff --git a/src/extra_tests/fuzzers/jigs/invert.cpp b/src/extra_tests/fuzzers/jigs/invert.cpp new file mode 100644 index 000000000..fcda5770e --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/invert.cpp @@ -0,0 +1,81 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" +#include <botan/numthry.h> + +BigInt inverse_mod_ref(const BigInt& n, const BigInt& mod) + { + if(n == 0) + return 0; + + BigInt u = mod, v = n; + BigInt B = 0, D = 1; + + while(u.is_nonzero()) + { + const size_t u_zero_bits = low_zero_bits(u); + u >>= u_zero_bits; + for(size_t i = 0; i != u_zero_bits; ++i) + { + //B.cond_sub(B.is_odd(), mod); + if(B.is_odd()) + { B -= mod; } + B >>= 1; + } + + const size_t v_zero_bits = low_zero_bits(v); + v >>= v_zero_bits; + for(size_t i = 0; i != v_zero_bits; ++i) + { + if(D.is_odd()) + { D -= mod; } + D >>= 1; + } + + if(u >= v) { u -= v; B -= D; } + else { v -= u; D -= B; } + } + + if(v != 1) + return 0; // no modular inverse + + while(D.is_negative()) D += mod; + while(D >= mod) D -= mod; + + return D; + } + + +void fuzz(const uint8_t in[], size_t len) + { + const BigInt x = BigInt::decode(in, len / 2); + BigInt mod = BigInt::decode(in + len / 2, len / 2); + + mod.set_bit(0); + + if(mod < 3 || x >= mod) + return; + + BigInt ref = inverse_mod_ref(x, mod); + BigInt ct = ct_inverse_mod_odd_modulus(x, mod); + //BigInt mon = normalized_montgomery_inverse(x, mod); + + if(ref != ct) + { + std::cout << "X = " << x << "\n"; + std::cout << "P = " << mod << "\n"; + std::cout << "GCD = " << gcd(x, mod) << "\n"; + std::cout << "Ref = " << ref << "\n"; + std::cout << "CT = " << ct << "\n"; + //std::cout << "Mon = " << mon << "\n"; + + std::cout << "RefCheck = " << (ref*ref)%mod << "\n"; + std::cout << "CTCheck = " << (ct*ct)%mod << "\n"; + //std::cout << "MonCheck = " << (mon*mon)%mod << "\n"; + abort(); + } + } + diff --git a/src/extra_tests/fuzzers/jigs/os2ecp.cpp b/src/extra_tests/fuzzers/jigs/os2ecp.cpp new file mode 100644 index 000000000..2b939eb5b --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/os2ecp.cpp @@ -0,0 +1,37 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" +#include <botan/ec_group.h> +#include <botan/point_gfp.h> + +void check_os2ecp(const EC_Group& group, const uint8_t in[], size_t len) + { + try + { + PointGFp point = OS2ECP(in, len, group.get_curve()); + } + catch(Botan::Exception& e) {} + } + +void fuzz(const uint8_t in[], size_t len) + { + static EC_Group p192("secp192r1"); + static EC_Group p224("secp224r1"); + static EC_Group p256("secp256r1"); + static EC_Group p384("secp384r1"); + static EC_Group p521("secp521r1"); + static EC_Group bp256("brainpool256r1"); + static EC_Group bp512("brainpool512r1"); + + check_os2ecp(p192, in, len); + check_os2ecp(p224, in, len); + check_os2ecp(p256, in, len); + check_os2ecp(p384, in, len); + check_os2ecp(p521, in, len); + check_os2ecp(p521, in, len); + check_os2ecp(bp256, in, len); + check_os2ecp(bp512, in, len); + } diff --git a/src/extra_tests/fuzzers/jigs/pkcs1.cpp b/src/extra_tests/fuzzers/jigs/pkcs1.cpp new file mode 100644 index 000000000..889308f0e --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/pkcs1.cpp @@ -0,0 +1,68 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" + +#include <botan/eme_pkcs.h> +#include <botan/hex.h> + +secure_vector<byte> simple_pkcs1_unpad(const byte in[], size_t len) + { + if(len < 10) + throw Botan::Decoding_Error("bad len"); + + if(in[0] != 2) + throw Botan::Decoding_Error("bad field"); + + for(size_t i = 1; i < len; ++i) + { + if(in[i] == 0) + { + if(i < 9) + throw Botan::Decoding_Error("insufficient padding bytes"); + return secure_vector<byte>(in + i + 1, in + len); + } + } + + throw Botan::Decoding_Error("delim not found"); + } + +void fuzz(const uint8_t in[], size_t len) + { + static EME_PKCS1v15 pkcs1; + + secure_vector<byte> lib_result, ref_result; + bool lib_rejected = false, ref_rejected = false; + + try + { + byte valid_mask = 0; + secure_vector<byte> decoded = ((EME*)&pkcs1)->unpad(valid_mask, in, len); + + if(valid_mask == 0) + lib_rejected = false; + else if(valid_mask == 0xFF) + lib_rejected = true; + else + abort(); + } + catch(Botan::Decoding_Error&) { lib_rejected = true; } + + try + { + ref_result = simple_pkcs1_unpad(in, len); + } + catch(Botan::Decoding_Error&) { ref_rejected = true; } + + FUZZER_ASSERT_EQUAL(lib_rejected, ref_rejected); + + if(lib_result != ref_result) + { + std::cerr << hex_encode(lib_result) << " != ref \n" + << hex_encode(ref_result) << std::endl; + abort(); + } + + } diff --git a/src/extra_tests/fuzzers/jigs/pkcs8.cpp b/src/extra_tests/fuzzers/jigs/pkcs8.cpp new file mode 100644 index 000000000..69e2c193f --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/pkcs8.cpp @@ -0,0 +1,20 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" + +#include <botan/pkcs8.h> +#include <botan/system_rng.h> + +void fuzz(const uint8_t in[], size_t len) + { + try + { + System_RNG rng; + DataSource_Memory input(in, len); + std::unique_ptr<Private_Key> key(PKCS8::load_key(input, rng)); + } + catch(Botan::Exception& e) { } + } diff --git a/src/extra_tests/fuzzers/jigs/redc_p192.cpp b/src/extra_tests/fuzzers/jigs/redc_p192.cpp new file mode 100644 index 000000000..a27e6a37b --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/redc_p192.cpp @@ -0,0 +1,23 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "driver.h" +#include "ecc_helper.h" +#include <botan/curve_nistp.h> + +void fuzz(const uint8_t in[], size_t len) + { + static const BigInt& prime = Botan::prime_p192(); + static const BigInt prime_2 = prime * prime; + static Botan::Modular_Reducer prime_redc(prime); + + Botan::BigInt x = Botan::BigInt::decode(in, len); + + if(x < prime_2) + { + check_redc(Botan::redc_p192, prime_redc, prime, x); + } + } diff --git a/src/extra_tests/fuzzers/jigs/redc_p224.cpp b/src/extra_tests/fuzzers/jigs/redc_p224.cpp new file mode 100644 index 000000000..637d9e6fd --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/redc_p224.cpp @@ -0,0 +1,23 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "driver.h" +#include "ecc_helper.h" +#include <botan/curve_nistp.h> + +void fuzz(const uint8_t in[], size_t len) + { + static const BigInt& prime = Botan::prime_p224(); + static const BigInt prime_2 = prime * prime; + static Botan::Modular_Reducer prime_redc(prime); + + Botan::BigInt x = Botan::BigInt::decode(in, len); + + if(x < prime_2) + { + check_redc(Botan::redc_p224, prime_redc, prime, x); + } + } diff --git a/src/extra_tests/fuzzers/jigs/redc_p256.cpp b/src/extra_tests/fuzzers/jigs/redc_p256.cpp new file mode 100644 index 000000000..86f0910a0 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/redc_p256.cpp @@ -0,0 +1,23 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "driver.h" +#include "ecc_helper.h" +#include <botan/curve_nistp.h> + +void fuzz(const uint8_t in[], size_t len) + { + static const BigInt& prime = Botan::prime_p256(); + static const BigInt prime_2 = prime * prime; + static Botan::Modular_Reducer prime_redc(prime); + + Botan::BigInt x = Botan::BigInt::decode(in, len); + + if(x < prime_2) + { + check_redc(Botan::redc_p256, prime_redc, prime, x); + } + } diff --git a/src/extra_tests/fuzzers/jigs/redc_p384.cpp b/src/extra_tests/fuzzers/jigs/redc_p384.cpp new file mode 100644 index 000000000..9a9ac896a --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/redc_p384.cpp @@ -0,0 +1,23 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "driver.h" +#include "ecc_helper.h" +#include <botan/curve_nistp.h> + +void fuzz(const uint8_t in[], size_t len) + { + static const BigInt& prime = Botan::prime_p384(); + static const BigInt prime_2 = prime * prime; + static Botan::Modular_Reducer prime_redc(prime); + + Botan::BigInt x = Botan::BigInt::decode(in, len); + + if(x < prime_2) + { + check_redc(Botan::redc_p384, prime_redc, prime, x); + } + } diff --git a/src/extra_tests/fuzzers/jigs/redc_p521.cpp b/src/extra_tests/fuzzers/jigs/redc_p521.cpp new file mode 100644 index 000000000..fe164217d --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/redc_p521.cpp @@ -0,0 +1,23 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "driver.h" +#include "ecc_helper.h" +#include <botan/curve_nistp.h> + +void fuzz(const uint8_t in[], size_t len) + { + static const BigInt& prime = Botan::prime_p521(); + static const BigInt prime_2 = prime * prime; + static Botan::Modular_Reducer prime_redc(prime); + + Botan::BigInt x = Botan::BigInt::decode(in, len); + + if(x < prime_2) + { + check_redc(Botan::redc_p521, prime_redc, prime, x); + } + } diff --git a/src/extra_tests/fuzzers/jigs/ressol.cpp b/src/extra_tests/fuzzers/jigs/ressol.cpp new file mode 100644 index 000000000..011194866 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/ressol.cpp @@ -0,0 +1,50 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "driver.h" +#include <botan/numthry.h> +#include <botan/system_rng.h> + +void fuzz(const uint8_t in[], size_t len) + { + if(len % 2 != 0) + return; + + const BigInt a = BigInt::decode(in, len / 2); + const BigInt n = BigInt::decode(in + len / 2, len / 2); + + try { + BigInt a_sqrt = ressol(a, n); + + if(a_sqrt > 0) + { + /* + * If n is not prime then the result of ressol will be bogus. But + * this function is exposed to untrusted inputs (via OS2ECP) so + * should not hang or crash even with composite modulus. + * If the result is incorrect, check if n is a prime: if it is + * then z != a is a bug. + */ + BigInt z = (a_sqrt * a_sqrt) % n; + BigInt a_redc = a % n; + if(z != a_redc) + { + if(is_prime(n, system_rng(), 64)) + { + std::cout << "A = " << a << "\n"; + std::cout << "Ressol = " << a_sqrt << "\n"; + std::cout << "N = " << n << "\n"; + std::cout << "Z = " << z << "\n"; + abort(); + } + } + } + } + catch(Botan::Exception& e) {} + + return; + } + diff --git a/src/extra_tests/fuzzers/jigs/tls_client.cpp b/src/extra_tests/fuzzers/jigs/tls_client.cpp new file mode 100644 index 000000000..e0fd039c9 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/tls_client.cpp @@ -0,0 +1,85 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "driver.h" +#include <botan/tls_client.h> +#include <botan/system_rng.h> + +class Fuzzer_TLS_Client_Creds : public Credentials_Manager + { + public: + void verify_certificate_chain(const std::string& type, + const std::string& purported_hostname, + const std::vector<X509_Certificate>& cert_chain) override + { + try + { + Credentials_Manager::verify_certificate_chain(type, + purported_hostname, + cert_chain); + } + catch(std::exception& e) {} + } + + std::string psk_identity_hint(const std::string&, const std::string&) override { return "psk_hint"; } + std::string psk_identity(const std::string&, const std::string&, const std::string&) override { return "psk_id"; } + SymmetricKey psk(const std::string&, const std::string&, const std::string&) override + { + return SymmetricKey("AABBCCDDEEFF00112233445566778899"); + } + }; + +void fuzz(const uint8_t in[], size_t len) + { + if(len == 0) + return; + + auto dev_null = [](const byte[], size_t) {}; + + auto ignore_alerts = [](TLS::Alert, const byte[], size_t) {}; + auto ignore_hs = [](const TLS::Session&) { abort(); return true; }; + + Botan::System_RNG rng; + TLS::Session_Manager_Noop session_manager; + TLS::Policy policy; + TLS::Protocol_Version client_offer = TLS::Protocol_Version::TLS_V12; + TLS::Server_Information info("server.name", 443); + const std::vector<std::string> protocols_to_offer = { "fuzz/1.0", "http/1.1", "bunny/1.21.3" }; + Fuzzer_TLS_Client_Creds creds; + + TLS::Client client(dev_null, + dev_null, + ignore_alerts, + ignore_hs, + session_manager, + creds, + policy, + rng, + info, + client_offer, + protocols_to_offer); + + try + { + while(len > 0) + { + const size_t write_len = in[0]; + const size_t left = len - 1; + + const size_t consumed = std::min(left, write_len); + + client.received_data(in + 1, consumed); + + in += consumed + 1; + len -= consumed + 1; + } + } + catch(std::exception& e) + { + } + + } + diff --git a/src/extra_tests/fuzzers/jigs/tls_client_hello.cpp b/src/extra_tests/fuzzers/jigs/tls_client_hello.cpp new file mode 100644 index 000000000..5705dca91 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/tls_client_hello.cpp @@ -0,0 +1,21 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ +#include "driver.h" +#include <botan/internal/tls_messages.h> + +void fuzz(const uint8_t in[], size_t len) + { + try + { + std::vector<uint8_t> v(in, in + len); + Botan::TLS::Client_Hello ch(v); + + printf("%s\n", ch.version().to_string().c_str()); + if(ch.version() == Botan::TLS::Protocol_Version::TLS_V12) + abort(); + } + catch(Botan::Exception& e) {printf("%s\n", e.what()); } + } diff --git a/src/extra_tests/fuzzers/jigs/tls_server.cpp b/src/extra_tests/fuzzers/jigs/tls_server.cpp new file mode 100644 index 000000000..510f7f7b7 --- /dev/null +++ b/src/extra_tests/fuzzers/jigs/tls_server.cpp @@ -0,0 +1,179 @@ +/* +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "driver.h" +#include <botan/tls_server.h> +#include <botan/system_rng.h> + +const char* fixed_rsa_key = + "-----BEGIN PRIVATE KEY-----\n" + "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCe6qqpMQVJ7zCJ\n" + "oSnpxia0yO6M7Ie3FGqPcd0DzueC+kWPvuHQ+PpP5vfO6qqRaDVII37PFX5NUZQm\n" + "GK/rAm7spjIHTCMgqSZ8pN13LU8m1gDwIdu9al16LXN9zZjB67uLlFn2trtLi234\n" + "i0cnyeF8IC0cz7tgCOzMSVEBcqJjkdgGrZ3WUgOXecVm2lXVrYlEiaSxFp4VOE9k\n" + "RFeVrELCjmNtc4hRd1yJsF+vObCtvyqGYQE1Qcb0MVSQDBHMkiUVmO6zuW7td5ef\n" + "O/1OyntQJGyVa+SnWbkSLCybta2J7MreHENrF5GA0K1KL140SNRHeWifRMuNQua7\n" + "qmKXMBTFAgMBAAECggEAIk3fxyQI0zvpy1vZ01ft1QqmzA7nAPNMSWi33/GS8iga\n" + "SfxXfKeySPs/tQ/dAARxs//NiOBH4mLgyxR7LQzaawU5OXALCSraXv+ruuUx990s\n" + "WKnGaG4EfbJAAwEVn47Gbkv425P4fEc91vAhzQn8PbIoatbAyOtESpjs/pYDTeC/\n" + "mnJId8gqO90cqyRECEMjk9sQ8iEjWPlik4ayGlUVbeeMu6/pJ9F8IZEgkLZiNDAB\n" + "4anmOFaT7EmqUjI4IlcaqfbbXyDXlvWUYukidEss+CNvPuqbQHBDnpFVvBxdDR2N\n" + "Uj2D5Xd5blcIe2/+1IVRnznjoQ5zvutzb7ThBmMehQKBgQDOITKG0ht2kXLxjVoR\n" + "r/pVpx+f3hs3H7wE0+vrLHoQgkVjpMWXQ47YuZTT9rCOOYNI2cMoH2D27t1j78/B\n" + "9kGYABUVpvQQ+6amqJDI1eYI6e68TPueEDjeALfSCdmPNiI3lZZrCIK9XLpkoy8K\n" + "tGYBRRJ+JJxjj1zPXj9SGshPgwKBgQDFXUtoxY3mCStH3+0b1qxGG9r1L5goHEmd\n" + "Am8WBYDheNpL0VqPNzouhuM/ZWMGyyAs/py6aLATe+qhR1uX5vn7LVZwjCSONZ4j\n" + "7ieEEUh1BHetPI1oI5PxgokRYfVuckotqVseanI/536Er3Yf2FXNQ1/ceVp9WykX\n" + "3mYTKMhQFwKBgQDKakcXpZNaZ5IcKdZcsBZ/rdGcR5sqEnursf9lvRNQytwg8Vkn\n" + "JSxNHlBLpV/TCh8lltHRwJ6TXhUBYij+KzhWbx5FWOErHDOWTMmArqtp7W6GcoJT\n" + "wVJWjxXzp8CApYQMWVSQXpckJL7UvHohZO0WKiHyxTjde5aD++TqV2qEyQKBgBbD\n" + "jvoTpy08K4DLxCZs2Uvw1I1pIuylbpwsdrGciuP2s38BM6fHH+/T4Qwj3osfDKQD\n" + "7gHWJ1Dn/wUBHQBlRLoC3bB3iZPZfVb5lhc2gxv0GvWhQVIcoGi/vJ2DpfJKPmIL\n" + "4ZWdg3X5dm9JaZ98rVDSj5D3ckd5J0E4hp95GbmbAoGBAJJHM4O9lx60tIjw9Sf/\n" + "QmKWyUk0NLnt8DcgRMW7fVxtzPNDy9DBKGIkDdWZ2s+ForICA3C9WSxBC1EOEHGG\n" + "xkg2xKt66CeutGroP6M191mHQrRClt1VbEYzQFX21BCk5kig9i/BURyoTHtFiV+t\n" + "kbf4VLg8Vk9u/R3RU1HsYWhe\n" + "-----END PRIVATE KEY-----\n"; + +const char* fixed_rsa_cert = + "-----BEGIN CERTIFICATE-----\n" + "MIIDUDCCAjgCCQD7pIb1ZsoafjANBgkqhkiG9w0BAQsFADBqMQswCQYDVQQGEwJW\n" + "VDEQMA4GA1UECAwHVmVybW9udDEWMBQGA1UEBwwNVGhlIEludGVybmV0czEUMBIG\n" + "A1UECgwLTWFuZ29zIFIgVXMxGzAZBgNVBAMMEnNlcnZlci5leGFtcGxlLmNvbTAe\n" + "Fw0xNjAxMDYxNzQ3MjNaFw0yNjAxMDMxNzQ3MjNaMGoxCzAJBgNVBAYTAlZUMRAw\n" + "DgYDVQQIDAdWZXJtb250MRYwFAYDVQQHDA1UaGUgSW50ZXJuZXRzMRQwEgYDVQQK\n" + "DAtNYW5nb3MgUiBVczEbMBkGA1UEAwwSc2VydmVyLmV4YW1wbGUuY29tMIIBIjAN\n" + "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnuqqqTEFSe8wiaEp6cYmtMjujOyH\n" + "txRqj3HdA87ngvpFj77h0Pj6T+b3zuqqkWg1SCN+zxV+TVGUJhiv6wJu7KYyB0wj\n" + "IKkmfKTddy1PJtYA8CHbvWpdei1zfc2Yweu7i5RZ9ra7S4tt+ItHJ8nhfCAtHM+7\n" + "YAjszElRAXKiY5HYBq2d1lIDl3nFZtpV1a2JRImksRaeFThPZERXlaxCwo5jbXOI\n" + "UXdcibBfrzmwrb8qhmEBNUHG9DFUkAwRzJIlFZjus7lu7XeXnzv9Tsp7UCRslWvk\n" + "p1m5Eiwsm7WtiezK3hxDaxeRgNCtSi9eNEjUR3lon0TLjULmu6pilzAUxQIDAQAB\n" + "MA0GCSqGSIb3DQEBCwUAA4IBAQA1eZGc/4V7z/E/6eG0hVkzoAZeuTcSP7WqBSx+\n" + "OP2yh0163UYjoa6nehmkKYQQ9PbYPZGzIcl+dBFyYzy6jcp0NdtzpWnTFrjl4rMq\n" + "akcQ1D0LTYjJXVP9G/vF/SvatOFeVTnQmLlLt/a8ZtRUINqejeZZPzH8ifzFW6tu\n" + "mlhTVIEKyPHpxClh5Y3ubw/mZYygekFTqMkTx3FwJxKU8J6rYGZxanWAODUIvCUo\n" + "Fxer1qC5Love3uWl3vXPLEZWZdORnExSRByzz2immBP2vX4zYZoeZRhTQ9ae1TIV\n" + "Dk02a/1AOJZdZReDbgXhlqaUx5pk/rzo4mDzvu5HSCeXmClz\n" + "-----END CERTIFICATE-----\n"; + +class Fuzzer_TLS_Server_Creds : public Credentials_Manager + { + public: + Fuzzer_TLS_Server_Creds() + { + DataSource_Memory cert_in(fixed_rsa_cert); + DataSource_Memory key_in(fixed_rsa_key); + + m_rsa_cert.reset(new Botan::X509_Certificate(cert_in)); + //m_rsa_key.reset(Botan::PKCS8::load_key(key_in, Botan::system_rng())); + } + + void verify_certificate_chain(const std::string& type, + const std::string& purported_hostname, + const std::vector<X509_Certificate>& cert_chain) override + { + try + { + Credentials_Manager::verify_certificate_chain(type, + purported_hostname, + cert_chain); + } + catch(std::exception& e) {} + } + + std::vector<Botan::X509_Certificate> cert_chain( + const std::vector<std::string>& algos, + const std::string& type, + const std::string& hostname) override + { + std::vector<Botan::X509_Certificate> v; + + for(auto algo : algos) + { + if(algo == "RSA") + { + v.push_back(*m_rsa_cert); + break; + } + } + + return v; + } + + Botan::Private_Key* private_key_for(const Botan::X509_Certificate& cert, + const std::string& /*type*/, + const std::string& /*context*/) override + { + return m_rsa_key.get(); + } + + std::string psk_identity_hint(const std::string&, const std::string&) override { return "psk_hint"; } + std::string psk_identity(const std::string&, const std::string&, const std::string&) override { return "psk_id"; } + SymmetricKey psk(const std::string&, const std::string&, const std::string&) override + { + return SymmetricKey("AABBCCDDEEFF00112233445566778899"); + } + private: + std::unique_ptr<Botan::X509_Certificate> m_rsa_cert; + std::unique_ptr<Botan::Private_Key> m_rsa_key; + }; + +void fuzz(const uint8_t in[], size_t len) + { + if(len == 0) + return; + + auto dev_null = [](const byte[], size_t) {}; + + auto ignore_alerts = [](TLS::Alert, const byte[], size_t) {}; + auto ignore_hs = [](const TLS::Session&) { return true; }; + + Botan::System_RNG rng; + TLS::Session_Manager_Noop session_manager; + TLS::Policy policy; + TLS::Server_Information info("server.name", 443); + Fuzzer_TLS_Server_Creds creds; + + auto next_proto_fn = [](const std::vector<std::string>& protos) -> std::string { + if(protos.size() > 1) + return protos[0]; + else + return "fuzzed"; + }; + + const bool is_datagram = (len % 2 == 0); + + TLS::Server server(dev_null, + dev_null, + ignore_alerts, + ignore_hs, + session_manager, + creds, + policy, + rng, + next_proto_fn, + is_datagram); + + try + { + while(len > 0) + { + const size_t write_len = in[0]; + const size_t left = len - 1; + + const size_t consumed = std::min(left, write_len); + + server.received_data(in + 1, consumed); + + in += consumed + 1; + len -= consumed + 1; + } + } + catch(std::exception& e) + { + } + } |