Skip to content

Commit

Permalink
Decouple support for explicit curves with legacy_ec_point
Browse files Browse the repository at this point in the history
Both are deprecated but for different reasons, and in the short term
it's reasonable to want to disable legacy_ec_point while still
supporting explicit curve encodings.
  • Loading branch information
randombit committed Jan 19, 2025
1 parent 53c5f92 commit 22ef4bb
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 11 deletions.
44 changes: 36 additions & 8 deletions src/lib/pubkey/ec_group/ec_group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <botan/ber_dec.h>
#include <botan/der_enc.h>
#include <botan/mutex.h>
#include <botan/numthry.h>
#include <botan/pem.h>
#include <botan/reducer.h>
#include <botan/rng.h>
Expand Down Expand Up @@ -219,8 +220,6 @@ std::pair<std::shared_ptr<EC_Group_Data>, bool> EC_Group::BER_decode_EC_group(st

return std::make_pair(data, false);
} else if(next_obj_type == ASN1_Type::Sequence) {
#if defined(BOTAN_HAS_LEGACY_EC_POINT)

BigInt p, a, b, order, cofactor;
std::vector<uint8_t> base_pt;
std::vector<uint8_t> seed;
Expand All @@ -246,7 +245,8 @@ std::pair<std::shared_ptr<EC_Group_Data>, bool> EC_Group::BER_decode_EC_group(st
throw Decoding_Error("ECC p parameter is invalid size");
}

if(p.is_negative() || !is_bailie_psw_probable_prime(p)) {
Modular_Reducer mod_p(p);
if(p.is_negative() || !is_bailie_psw_probable_prime(p, mod_p)) {
throw Decoding_Error("ECC p parameter is not a prime");
}

Expand All @@ -266,14 +266,42 @@ std::pair<std::shared_ptr<EC_Group_Data>, bool> EC_Group::BER_decode_EC_group(st
throw Decoding_Error("Invalid ECC cofactor parameter");
}

const auto [g_x, g_y] = Botan::OS2ECP(base_pt.data(), base_pt.size(), p, a, b);
auto [g_x, g_y] = [&]() {
const size_t p_bytes = p.bytes();
const uint8_t hdr = base_pt[0];

if(hdr == 0x04 && base_pt.size() == 1 + 2 * p_bytes) {
BigInt x = BigInt::decode(&base_pt[1], p_bytes);
BigInt y = BigInt::decode(&base_pt[p_bytes + 1], p_bytes);

if(x < p && y < p) {
return std::make_pair(x, y);
}
} else if((hdr == 0x02 || hdr == 0x03) && base_pt.size() == 1 + p_bytes) {
BigInt x = BigInt::decode(&base_pt[1], p_bytes);
BigInt y = sqrt_modulo_prime(((x * x + a) * x + b) % p, p);

if(x < p && y >= 0) {
const bool y_mod_2 = (hdr & 0x01) == 1;
if(y.get_bit(0) != y_mod_2) {
y = p - y;
}

return std::make_pair(x, y);
}
}

throw Decoding_Error("Invalid ECC base point encoding");
}();

auto y2 = mod_p.square(g_y);
auto x3_ax_b = mod_p.reduce(mod_p.cube(g_x) + mod_p.multiply(a, g_x) + b);
if(y2 != x3_ax_b) {
throw Decoding_Error("Invalid ECC base point");
}

auto data = ec_group_data().lookup_or_create(p, a, b, g_x, g_y, order, cofactor, OID(), source);
return std::make_pair(data, true);
#else
BOTAN_UNUSED(source);
throw Decoding_Error("Decoding explicit ECC parameters is not supported");
#endif
} else if(next_obj_type == ASN1_Type::Null) {
throw Decoding_Error("Decoding ImplicitCA ECC parameters is not supported");
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pubkey/ec_group/legacy_ec_point/curve_gfp.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#ifndef BOTAN_GFP_CURVE_H_
#define BOTAN_GFP_CURVE_H_

// TODO(Botan4) delete this header

#include <botan/bigint.h>

// Currently exposed in EC_Point
Expand Down
12 changes: 9 additions & 3 deletions src/lib/pubkey/ec_group/legacy_ec_point/ec_point.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#ifndef BOTAN_EC_POINT_H_
#define BOTAN_EC_POINT_H_

// TODO(Botan4) delete this header

#include <botan/curve_gfp.h>
#include <botan/ec_point_format.h>
#include <botan/exceptn.h>
Expand All @@ -20,9 +22,13 @@ namespace Botan {
/**
* Deprecated elliptic curve type
*
* Use EC_AffinePoint in new code
* Use EC_AffinePoint in new code; this type is no longer used internally at all
* except to support very unfortunate (and deprecated) curve types, specifically
* those with a cofactor, or with unreasonable sizes (above 521 bits), which
* cannot be accomodated by the new faster EC library in math/pcurves. For
* normal curves EC_AffinePoint will typically be 2 or 3 times faster.
*
* This type will be removed/hidden in Botan4
* This type will be completely removed in Botan4
*/
class BOTAN_PUBLIC_API(2, 0) EC_Point final {
public:
Expand Down Expand Up @@ -438,7 +444,7 @@ BOTAN_DEPRECATED("Use EC_AffinePoint::deserialize")
std::pair<BigInt, BigInt> BOTAN_UNSTABLE_API
OS2ECP(const uint8_t data[], size_t data_len, const BigInt& curve_p, const BigInt& curve_a, const BigInt& curve_b);

BOTAN_DEPRECATED("Use EC_Group::OS2ECP")
BOTAN_DEPRECATED("Use EC_AffinePoint::deserialize")
EC_Point BOTAN_UNSTABLE_API OS2ECP(std::span<const uint8_t> data, const CurveGFp& curve);

// The name used for this type in older versions
Expand Down

0 comments on commit 22ef4bb

Please sign in to comment.