aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/ec_group
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-06-20 21:55:44 -0400
committerJack Lloyd <[email protected]>2018-06-20 21:55:44 -0400
commitee4813b2ce873c6965391c0543bf4dfc25fa2338 (patch)
tree0866c9bb312a5c3e0568feb20a5b31b82c1c9202 /src/lib/pubkey/ec_group
parenteb437358ede244386bd7cbee69289ceeb8984ae9 (diff)
Attempt to verify decoded ECC groups are using prime fields
Otherwise ressol (part of point decompression) can end up in very long loop. OSS-Fuzz 9011
Diffstat (limited to 'src/lib/pubkey/ec_group')
-rw-r--r--src/lib/pubkey/ec_group/ec_group.cpp39
1 files changed, 37 insertions, 2 deletions
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);