Make built-in curves static. This replaces our dynamically creating singleton EC_GROUPs from curve data with static EC_GROUP instances. They're just shy of being fully static because delocate still forces us go to through CRYPTO_once to initialize structures with pointers. (Though, without delocate, the loader would need similar initialization via a runtime relocation.) This means we can now have functions like EC_group_p256(), analogous to EVP_sha256(). These are infallible functions that return const EC_GROUP pointers. Although there is an initial 2KiB hit to binary size (now we precompute a few more Montgomery values), I'm hoping it'll eventually help binaries that only use a few of the curves to drop the others. Also it removes some locks used to initialize the static curve objects, as well as removing an annoying error condition. Bug: 20 Change-Id: Id051c5439f2b2fe2b09bf10964d656503ee27d9e Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60931 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ec.h b/include/openssl/ec.h index dd5259b..f1a77b2 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h
@@ -101,8 +101,24 @@ // Elliptic curve groups. -// EC_GROUP_new_by_curve_name returns a fresh EC_GROUP object for the elliptic -// curve specified by |nid|, or NULL on unsupported NID or allocation failure. +// EC_group_p224 returns an |EC_GROUP| for P-224, also known as secp224r1. +OPENSSL_EXPORT const EC_GROUP *EC_group_p224(void); + +// EC_group_p256 returns an |EC_GROUP| for P-256, also known as secp256r1 or +// prime256v1. +OPENSSL_EXPORT const EC_GROUP *EC_group_p256(void); + +// EC_group_p384 returns an |EC_GROUP| for P-384, also known as secp384r1. +OPENSSL_EXPORT const EC_GROUP *EC_group_p384(void); + +// EC_group_p521 returns an |EC_GROUP| for P-521, also known as secp521r1. +OPENSSL_EXPORT const EC_GROUP *EC_group_p521(void); + +// EC_GROUP_new_by_curve_name returns the |EC_GROUP| object for the elliptic +// curve specified by |nid|, or NULL on unsupported NID. For OpenSSL +// compatibility, this function returns a non-const pointer which may be passed +// to |EC_GROUP_free|. However, the resulting object is actually static and +// calling |EC_GROUP_free| is optional. // // The supported NIDs are: // NID_secp224r1 (P-224), @@ -110,6 +126,9 @@ // NID_secp384r1 (P-384), // NID_secp521r1 (P-521) // +// Calling this function causes all four curves to be linked into the binary. +// Prefer calling |EC_group_*| to allow the static linker to drop unused curves. +// // If in doubt, use |NID_X9_62_prime256v1|, or see the curve25519.h header for // more modern primitives. OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 00986cf..b7bc74c 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h
@@ -259,8 +259,15 @@ unsigned enc_flags); // EC_KEY_parse_curve_name parses a DER-encoded OBJECT IDENTIFIER as a curve -// name from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP| -// or NULL on error. +// name from |cbs| and advances |cbs|. It returns the decoded |EC_GROUP| or NULL +// on error. +// +// This function returns a non-const pointer which may be passed to +// |EC_GROUP_free|. However, the resulting object is actually static and calling +// |EC_GROUP_free| is optional. +// +// TODO(davidben): Make this return a const pointer, if it does not break too +// many callers. OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs); // EC_KEY_marshal_curve_name marshals |group| as a DER-encoded OBJECT IDENTIFIER @@ -269,10 +276,16 @@ OPENSSL_EXPORT int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group); // EC_KEY_parse_parameters parses a DER-encoded ECParameters structure (RFC -// 5480) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP| -// or NULL on error. It supports the namedCurve and specifiedCurve options, but -// use of specifiedCurve is deprecated. Use |EC_KEY_parse_curve_name| -// instead. +// 5480) from |cbs| and advances |cbs|. It returns the resulting |EC_GROUP| or +// NULL on error. It supports the namedCurve and specifiedCurve options, but use +// of specifiedCurve is deprecated. Use |EC_KEY_parse_curve_name| instead. +// +// This function returns a non-const pointer which may be passed to +// |EC_GROUP_free|. However, the resulting object is actually static and calling +// |EC_GROUP_free| is optional. +// +// TODO(davidben): Make this return a const pointer, if it does not break too +// many callers. OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_parameters(CBS *cbs);