[erlang-questions] ERL-823: SSL cipher_suites too limited when compiling with OPENSSL_NO_EC=1

Nicholas Lundgaard <>
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