diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/math/numbertheory/numthry.cpp | 23 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.cpp | 39 |
2 files changed, 57 insertions, 5 deletions
diff --git a/src/lib/math/numbertheory/numthry.cpp b/src/lib/math/numbertheory/numthry.cpp index 593abb6a7..a312ba3a1 100644 --- a/src/lib/math/numbertheory/numthry.cpp +++ b/src/lib/math/numbertheory/numthry.cpp @@ -1,6 +1,6 @@ /* * Number Theory Functions -* (C) 1999-2011,2016 Jack Lloyd +* (C) 1999-2011,2016,2018 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -9,6 +9,7 @@ #include <botan/pow_mod.h> #include <botan/reducer.h> #include <botan/monty.h> +#include <botan/rng.h> #include <botan/internal/bit_ops.h> #include <botan/internal/mp_core.h> #include <botan/internal/ct_utils.h> @@ -519,7 +520,8 @@ bool is_prime(const BigInt& n, RandomNumberGenerator& rng, return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num); } - const size_t test_iterations = mr_test_iterations(n.bits(), prob, is_random); + const size_t test_iterations = + mr_test_iterations(n.bits(), prob, is_random && rng.is_seeded()); const BigInt n_minus_1 = n - 1; const size_t s = low_zero_bits(n_minus_1); @@ -533,7 +535,22 @@ bool is_prime(const BigInt& n, RandomNumberGenerator& rng, for(size_t i = 0; i != test_iterations; ++i) { - const BigInt a = BigInt::random_integer(rng, 2, n_minus_1); + BigInt a; + + if(rng.is_seeded()) + { + a = BigInt::random_integer(rng, 2, n_minus_1); + } + else + { + /* + * If passed a null RNG just use 2,3,5, ... as bases + * + * This is not ideal but in certain circumstances we need to + * test for primality but have no RNG available. + */ + a = PRIMES[i]; + } auto powm_a_n = monty_precompute(monty_n, a, powm_window); diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp index c859fc2fc..1ad2fbb6d 100644 --- a/src/lib/pubkey/ec_group/ec_group.cpp +++ b/src/lib/pubkey/ec_group/ec_group.cpp @@ -16,8 +16,15 @@ #include <botan/pem.h> #include <botan/reducer.h> #include <botan/mutex.h> +#include <botan/rng.h> #include <vector> +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include <botan/system_rng.h> +#elif defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32) + #include <botan/hmac_drbg.h> +#endif + namespace Botan { class EC_Group_Data final @@ -311,8 +318,36 @@ std::shared_ptr<EC_Group_Data> EC_Group::BER_decode_EC_group(const uint8_t bits[ .end_cons() .verify_end(); - if(p.bits() < 64 || p.is_negative() || a.is_negative() || b.is_negative() || order <= 0 || cofactor <= 0) - throw Decoding_Error("Invalid ECC parameters"); +#if defined(BOTAN_HAS_SYSTEM_RNG) + System_RNG rng; +#elif defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32) + /* + * This is not ideal because the data is attacker controlled, but + * it seems like it would be difficult for someone to come up + * with an valid ASN.1 encoding where the prime happened to pass + * Miller-Rabin test with exactly the values chosen when + * HMAC_DRBG is seeded with the overall data. + */ + HMAC_DRBG rng("SHA-256"); + rng.add_entropy(bits, len); +#else + Null_RNG rng; +#endif + + if(p.bits() < 64 || p.is_negative() || (is_prime(p, rng) == false)) + throw Decoding_Error("Invalid ECC p parameter"); + + if(a.is_negative() || a >= p) + throw Decoding_Error("Invalid ECC a parameter"); + + if(b <= 0 || b >= p) + throw Decoding_Error("Invalid ECC b parameter"); + + if(order <= 0) + throw Decoding_Error("Invalid ECC order parameter"); + + if(cofactor <= 0 || cofactor >= 16) + throw Decoding_Error("Invalid ECC cofactor parameter"); std::pair<BigInt, BigInt> base_xy = Botan::OS2ECP(base_pt.data(), base_pt.size(), p, a, b); |