Support explicit EC parameters for Brainpool curves - #14905
Support explicit EC parameters for Brainpool curves#14905sfarestam-iproov wants to merge 1 commit into
Conversation
d11eedf to
04cad16
Compare
ICAO Doc 9303 Part 12 Section 4.1.6.3 mandates that ECDSA keys in ePassport certificates use explicit EC domain parameters. PR pyca#12916 added explicit-to-named-curve mapping for P-256, P-384, and P-521. This extends the same mapping to brainpoolP256r1, brainpoolP384r1, and brainpoolP512r1, which are already supported as named curves. Domain parameters are from RFC 5639 Section 3. Both with-seed and without-seed variants are supported, matching the NIST curve pattern. This enables loading of ePassport CSCA and Document Signer certificates from 30+ countries (Germany, Sweden, Finland, Switzerland, etc.) that use Brainpool curves with explicit parameters per the ICAO standard. Closes pyca#5659 (Brainpool portion)
04cad16 to
ffdae46
Compare
|
Thanks for the contribution. One major challenge here is that we're actively interested in reducing the set of dependencies we have that keep us on OpenSSL in our wheels (see: https://cryptography.io/en/latest/statements/state-of-openssl/), and forks like aws-lc do not support brainpool. If we accept this patch then we will break all wheel users who rely on it when we switch off OpenSSL for our wheels. aws/aws-lc#2939 might be of interest to you. If aws-lc adds support then that significantly reduces my concern about long-term maintainability of this path. |
|
Thanks for the review and context — I wasn't aware of the AWS-LC wheel migration plans. I want to note that this PR does not add any new public-facing curves. BrainpoolP256r1, BrainpoolP384r1, and BrainpoolP512r1 are already exposed in the library's Python API ( That said, I understand the broader concern about investing in OpenSSL-only code paths. I've added a comment on aws/aws-lc#2939 with the ICAO 9303 ePassport use case, since that issue could use more real-world demand signal to help AWS prioritize. Happy to keep this PR open until the AWS-LC situation clarifies, or if you'd prefer to close it and revisit later, that works too. |
…1, brainpoolP512r1 EC group support (#3286) ### Issues: Resolves #2939 ### Description of changes: AWS-LC currently does not support Brainpool elliptic curves. This PR adds EC group support for the five Brainpool r1 prime curves defined in [RFC 5639](https://datatracker.ietf.org/doc/html/rfc5639): brainpoolP224r1, brainpoolP256r1, brainpoolP320r1, brainpoolP384r1, and brainpoolP512r1. The implementation follows the same pattern as secp256k1 — generic Montgomery arithmetic via `EC_GFp_mont_method()`, with no hand-optimized assembly. The only structural addition is `ec_group_set_a_mont()` for setting an arbitrary Montgomery-form `a` coefficient, since Brainpool curves have `a ≠ -3` (unlike NIST curves) and `a ≠ 0` (unlike secp256k1). The existing `ec_GFp_mont_dbl()` already handles this case correctly via its `a_is_minus3 == 0` code path. NIDs (925, 927, 929, 931, 933) and OIDs were already registered in `nid.h` and `obj_dat.h`. All domain parameters are sourced from RFC 5639 Sections 3.3–3.7, with OIDs from Section 4.1. This PR covers EC primitive support (key generation, ECDSA, ECDH). TLS negotiation support (RFC 7027 / RFC 8734) can follow in a separate PR. **Motivation:** These curves are required by [ICAO Doc 9303](https://www.icao.int/sites/default/files/publications/DocSeries/9303_p12_cons_en.pdf) (ePassport standard, 30+ countries), [BSI TR-03116-4](https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03116/BSI-TR-03116-4.html) (German federal regulation), and are blocking the [pyca/cryptography](https://github.com/pyca/cryptography) project from accepting Brainpool improvements ([pyca/cryptography#14905](pyca/cryptography#14905)). ### Call-outs: - **FIPS boundary**: The code is in `crypto/fipsmodule/ec/`. If adding curves inside the FIPS module is a concern for recertification, the implementation can be moved to `crypto/ec_extra/`. Please advise on the preferred placement. - **Arbitrary `a` coefficient**: Added a small helper `ec_group_set_a_mont()` (6 lines) to copy a Montgomery-form `a` value. This is the only new function beyond the existing curve template pattern. - **`make_tables.go` changes**: Added a `curveWithA` wrapper type and `writeCurveDataWithA()` function to emit `MontA` constants for curves where `a` is not -3 or 0. The standard `elliptic.CurveParams` in Go doesn't carry an `A` field (it assumes `a = -3`). ### Testing: - `BrainpoolKeygenSignVerify`: generates a key, signs a digest with ECDSA, verifies the signature, and checks that a corrupted signature is rejected — for all 5 curves. - `ECPKParmatersBio`: round-trip `i2d_ECPKParameters_bio` / `d2i_ECPKParameters_bio` for all 5 curves. - `GetNamedCurve`: dispatches Brainpool curve names for file-based test vectors. - Scalar base multiplication test vectors are not included in this PR (generating them requires a Go Brainpool library); they can be added as a follow-up. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
|
The aws-lc blocker is now resolved — Brainpool curve support (all five: P224, P256, P320, P384, P512) has been merged into aws-lc: aws/aws-lc#3286 This covers EC group creation, key generation, ECDSA sign/verify, ECDH, and EVP TLS encoded point operations for all five curves. The related feature request aws/aws-lc#2939 tracks broader TLS integration. This PR (explicit-parameter-to-named-curve mapping) doesn't add any new public-facing curves — it only extends the existing mapping so that keys encoded with explicit domain parameters (as mandated by ICAO 9303 for ePassport certificates) are recognized. It should be ready for review now. |
Summary
Extend the explicit-to-named-curve mapping (added in #12916) to cover brainpoolP256r1, brainpoolP384r1, and brainpoolP512r1. These curves are already supported as named curves — this PR adds only the
SpecifiedECDomainconstants so that keys encoded with explicit domain parameters are recognized and mapped to the existing named curves.Motivation
ICAO Doc 9303 (the international standard for machine-readable travel documents / ePassports), Part 12, Section 4.1.6.3 states:
The standard further recommends BSI TR-03111 for elliptic curve selection, which includes the Brainpool curves defined in RFC 5639.
Countries including Germany, Sweden, Finland, Switzerland, Austria, Cyprus, Lithuania, Latvia, Brazil, Russia, China, Turkey, and 20+ others issue ePassport CSCA and Document Signer certificates using Brainpool curves with explicit parameters, exactly as the standard mandates. These certificates are available in the publicly downloadable German CSCA Master List (580 certificates from 114 countries) and the Dutch CSCA Master List.
What this PR does
BRAINPOOLP256R1_DOMAIN,BRAINPOOLP384R1_DOMAIN,BRAINPOOLP512R1_DOMAINconstants (and_NO_SEEDvariants) toec_constants.rs, with domain parameters from RFC 5639 Section 3SpecifiedCurvebranch ofec_params_to_groupinec.rs, gated behind#[cfg(not(any(CRYPTOGRAPHY_IS_BORINGSSL, CRYPTOGRAPHY_IS_AWSLC)))](same as the existing named-curve Brainpool entries)openssl ecparam -name <curve> -param_enc explicit [-no_seed] -genkeytest_load_private_key_explicit_parametersandtest_load_public_key_explicit_parametersparametrized testsWhat this PR does NOT do
References