[erlang-questions] ERL-823: SSL cipher_suites too limited when compiling with OPENSSL_NO_EC=1
Nicholas Lundgaard
nalundgaard@REDACTED
Wed Jan 9 06:09:29 CET 2019
It seems that the remaining issue here, after removing the unneeded OPENSSL_NO_EC=1 in my Erlang/OTP build, has turned out to be a quirk of either OpenSSL with FIPS support in general, or RedHat/CentOS/Fedora's OpenSSL with FIPS support (even without FIPS enabled). It seems that the library categorically enforces a minimum of 256 bits for EC curves, and it rejects the definition of curves smaller than this, resulting in the run-time errors I have observed. I have opened up ERL-825 to cover this very distinct issue, and I wanted to post a final note on this thread to anyone interested in following along:
https://bugs.erlang.org/browse/ERL-825
I'm not sure this behavior is really worth fixing, but hopefully that issue will track whatever final resolution is reached.
I've closed https://bugs.erlang.org/browse/ERL-823.
Thanks & Regards,
—Nicholas Lundgaard
On Sat, Jan 5, 2019, at 3:39 PM, Per Hedeland wrote:
> On 2019-01-05 16:03, Nicholas Lundgaard wrote:
> > "Well, I'm not really an expert on this stuff"
> >
> > That makes two of us, at least... :)
>
> I was very impressed by your VerifyCurve function though.:-)
>
> > You're exactly right, when I compile OTP 21 on CentOS with or without OPENSSL_NO_EC2M, in either case, the built OTP correctly leaves ec_gf2m out of the public keys and filters out the GF2m named EC curves that aren't supported in the CentOS/RHEL OpenSSL.
> >
> > The remaining problem on RHEL/CentOS systems is that (for whatever reason) these systems lack support for a bunch of non-GF2m curves that Erlang/OTP's crypto/ssl modules claim to support, but emit runtime exceptions when you try to use them. It seems that is because they are explicitly hard-coded into the C headers in the OTP applications, when that information could be extracted or extrapolated from the linked SSL library itself (either dynamically at runtime or during compilation).
>
> Traditionally the build of the crypto.c NIF module has been based on
> the #defines in the *OpenSSL* headers, in particular
> openssl/opensslconf.h, which is supposed to describe how the OpenSSL
> libraries were built - this is where both OPENSSL_NO_EC and
> OPENSSL_NO_EC2M originates (i.e. from using the 'no-ec' and 'no-ec2m'
> options, respectively, in the OpenSSL configure/build).
>
> I don't think there are any more specific #defines for the individual
> ECC curves though - and in fact there doesn't seem to be any options
> for that in the OpenSSL build either. But in any case, using only the
> OpenSSL headers at build time, while linking dynamically with
> libcrypto, means that the libcrypto found at run time may not match
> the build, and runtime checks are motivated. And I believe both OTP
> crypto and OTP ssl do some such checks, but maybe they aren't 100%.
>
> > For clarity, I think this situation with these missing EC curves on RHEL/CentOS has been like this for many years with almost no change, so upgrading to a newer version of RHEL/CentOS/Amazon Linux isn't going to help. Here is the output from 'openssl ecparam -list_curves' on the latest (2018.03) Amazon Linux AMI running "OpenSSL 1.0.2k-fips 26 Jan 2017":
> >
> > openssl ecparam -list_curves
> > secp256k1 : SECG curve over a 256 bit prime field
> > secp384r1 : NIST/SECG curve over a 384 bit prime field
> > secp521r1 : NIST/SECG curve over a 521 bit prime field
> > prime256v1: X9.62/SECG curve over a 256 bit prime field
> >
> > And here is the output from 'openssl ecparam -list_curves' on a CentOS 6.9 box running "OpenSSL 1.0.1e-fips 11 Feb 2013". The older OpenSSL library omits the secp256k1 curve, but again, pretty similar output:
> >
> > openssl ecparam -list_curves
> > secp384r1 : NIST/SECG curve over a 384 bit prime field
> > secp521r1 : NIST/SECG curve over a 521 bit prime field
> > prime256v1: X9.62/SECG curve over a 256 bit prime field
>
> I also tried the 'ecparam -list_curves' on various systems, and was
> pretty surprised by the result... As you can see, the list you get on
> CentOS is way shorter than the list of successful invocations of your
> VerifyCurve funcion - and with a "normal" OpenSSL-1.0.1 build, I get
> this:
>
> secp112r1 : SECG/WTLS curve over a 112 bit prime field
> secp112r2 : SECG curve over a 112 bit prime field
> secp128r1 : SECG curve over a 128 bit prime field
> secp128r2 : SECG curve over a 128 bit prime field
> secp160k1 : SECG curve over a 160 bit prime field
> secp160r1 : SECG curve over a 160 bit prime field
> secp160r2 : SECG/WTLS curve over a 160 bit prime field
> secp192k1 : SECG curve over a 192 bit prime field
> secp224k1 : SECG curve over a 224 bit prime field
> secp224r1 : NIST/SECG curve over a 224 bit prime field
> secp256k1 : SECG curve over a 256 bit prime field
> secp384r1 : NIST/SECG curve over a 384 bit prime field
> secp521r1 : NIST/SECG curve over a 521 bit prime field
> prime192v1: NIST/X9.62/SECG curve over a 192 bit prime field
> prime192v2: X9.62 curve over a 192 bit prime field
> prime192v3: X9.62 curve over a 192 bit prime field
> prime239v1: X9.62 curve over a 239 bit prime field
> prime239v2: X9.62 curve over a 239 bit prime field
> prime239v3: X9.62 curve over a 239 bit prime field
> prime256v1: X9.62/SECG curve over a 256 bit prime field
> sect113r1 : SECG curve over a 113 bit binary field
> sect113r2 : SECG curve over a 113 bit binary field
> sect131r1 : SECG/WTLS curve over a 131 bit binary field
> sect131r2 : SECG curve over a 131 bit binary field
> sect163k1 : NIST/SECG/WTLS curve over a 163 bit binary field
> sect163r1 : SECG curve over a 163 bit binary field
> sect163r2 : NIST/SECG curve over a 163 bit binary field
> sect193r1 : SECG curve over a 193 bit binary field
> sect193r2 : SECG curve over a 193 bit binary field
> sect233k1 : NIST/SECG/WTLS curve over a 233 bit binary field
> sect233r1 : NIST/SECG/WTLS curve over a 233 bit binary field
> sect239k1 : SECG curve over a 239 bit binary field
> sect283k1 : NIST/SECG curve over a 283 bit binary field
> sect283r1 : NIST/SECG curve over a 283 bit binary field
> sect409k1 : NIST/SECG curve over a 409 bit binary field
> sect409r1 : NIST/SECG curve over a 409 bit binary field
> sect571k1 : NIST/SECG curve over a 571 bit binary field
> sect571r1 : NIST/SECG curve over a 571 bit binary field
> c2pnb163v1: X9.62 curve over a 163 bit binary field
> c2pnb163v2: X9.62 curve over a 163 bit binary field
> c2pnb163v3: X9.62 curve over a 163 bit binary field
> c2pnb176v1: X9.62 curve over a 176 bit binary field
> c2tnb191v1: X9.62 curve over a 191 bit binary field
> c2tnb191v2: X9.62 curve over a 191 bit binary field
> c2tnb191v3: X9.62 curve over a 191 bit binary field
> c2pnb208w1: X9.62 curve over a 208 bit binary field
> c2tnb239v1: X9.62 curve over a 239 bit binary field
> c2tnb239v2: X9.62 curve over a 239 bit binary field
> c2tnb239v3: X9.62 curve over a 239 bit binary field
> c2pnb272w1: X9.62 curve over a 272 bit binary field
> c2pnb304w1: X9.62 curve over a 304 bit binary field
> c2tnb359v1: X9.62 curve over a 359 bit binary field
> c2pnb368w1: X9.62 curve over a 368 bit binary field
> c2tnb431r1: X9.62 curve over a 431 bit binary field
> wap-wsg-idm-ecid-wtls1: WTLS curve over a 113 bit binary field
> wap-wsg-idm-ecid-wtls3: NIST/SECG/WTLS curve over a 163 bit binary field
> wap-wsg-idm-ecid-wtls4: SECG curve over a 113 bit binary field
> wap-wsg-idm-ecid-wtls5: X9.62 curve over a 163 bit binary field
> wap-wsg-idm-ecid-wtls6: SECG/WTLS curve over a 112 bit prime field
> wap-wsg-idm-ecid-wtls7: SECG/WTLS curve over a 160 bit prime field
> wap-wsg-idm-ecid-wtls8: WTLS curve over a 112 bit prime field
> wap-wsg-idm-ecid-wtls9: WTLS curve over a 160 bit prime field
> wap-wsg-idm-ecid-wtls10: NIST/SECG/WTLS curve over a 233 bit binary field
> wap-wsg-idm-ecid-wtls11: NIST/SECG/WTLS curve over a 233 bit binary field
> wap-wsg-idm-ecid-wtls12: WTLS curvs over a 224 bit prime field
> Oakley-EC2N-3:
> IPSec/IKE/Oakley curve #3 over a 155 bit binary field.
> Not suitable for ECDSA.
> Questionable extension field!
> Oakley-EC2N-4:
> IPSec/IKE/Oakley curve #4 over a 185 bit binary field.
> Not suitable for ECDSA.
> Questionable extension field!
>
> I haven't done a strict comparison of this output with the results of
> running your VerifyCurve function on the same system, but my
> impression is that all curves that were successful in the latter are
> also included in the former.
>
> I really wonder how the CentOS libcrypto was built. The "-fips" in the
> version might be a clue, but I believe this only means that it was
> built in such a way that "FIPS mode" is *available*, and thus it
> shouldn't affect something like the set of "supported" ECC curves.
> (If "FIPS mode" was *enforced*, it wouldn't work at all before OTP 20
> I believe, and this is definitely not the case.)
>
> Anyway, 'ecparam -list_curves' uses the OpenSSL function
> EC_get_builtin_curves(), which is documented in the OpenSSL man page
> with, among other info:
>
> Whilst the library can be used to create any curve using the functions
> described above, there are also a number of predefined curves that are
> available. In order to obtain a list of all of the predefined curves,
> call the function EC_get_builtin_curves.
>
> So I guess this isn't really the set of *supported* curves, and the
> OpenSSL ecparam(1) man page does say
>
> -list_curves
> If this options is specified ecparam will print out a list of all
> currently implemented EC parameters names and exit.
> ^^^^^^^^^^^
>
> - and there may already be some magic going on in the OTP 'crypto' app
> to create additional curves "on demand". But by now I'm way out of
> whatever expertise I may have...
>
> --Per
>
More information about the erlang-questions
mailing list