diff options
author | Jack Lloyd <[email protected]> | 2018-06-20 21:55:44 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-06-20 21:55:44 -0400 |
commit | ee4813b2ce873c6965391c0543bf4dfc25fa2338 (patch) | |
tree | 0866c9bb312a5c3e0568feb20a5b31b82c1c9202 /src/lib/pubkey/ec_group/ec_group.cpp | |
parent | eb437358ede244386bd7cbee69289ceeb8984ae9 (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/ec_group.cpp')
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.cpp | 39 |
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); |