aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/math/numbertheory/numthry.cpp23
-rw-r--r--src/lib/pubkey/ec_group/ec_group.cpp39
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);