# ECDHE key exchange with TLSv1

**URL:** <https://www.ruby-forum.com/t/ecdhe-key-exchange-with-tlsv1/191344>\
**Category:** NGINX\
**Created:** [July 9, 2010, 10:05pm UTC](https://www.ruby-forum.com/t/ecdhe-key-exchange-with-tlsv1/191344 "2010-07-09T22:05:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Calomel\_Org](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/59ef9b/32.png) [@Calomel\_Org](https://www.ruby-forum.com/u/Calomel_Org)\
**Post date:** [July 9, 2010, 10:05pm UTC](https://www.ruby-forum.com/t/ecdhe-key-exchange-with-tlsv1/191344/1 "2010-07-09T22:05:20Z")

</div>

Does Nginx support the elliptic curve cryptography ciphers like  
ECDHE-ECDSA-AES256-SHA available through OpenSSL v1.0.0a ?

I have built OpenSSL v1.0.0a and placed it in a separate directory. I  
then built nginx with --with-cc-opt=“-I /path\_openssl/include/”  
–with-ld-opt=“-L /path\_openssl/lib/” and it builds fine.

Nginx.conf has the following for SSL:

```
 ## SSL Certs
  ssl on;
  ssl_certificate /ssl/host.com_ssl.crt;
  ssl_certificate_key /ssl/host_ssl.key;
  ssl_ciphers ECDHE-ECDSA-AES256-SHA:AES256-SHA;
 #ssl_dhparam /ssl/host_dh.pem;
  ssl_prefer_server_ciphers on;
  ssl_protocols TLSv1;
  ssl_session_cache shared:SSL:1m;
  ssl_session_timeout 5m;

```

The daemon starts up correctly, but clients will only negotiate their  
SSL connection as AES256-SHA.

Does “ssl\_dhparam” need a PEM string? Any examples?

BTW, I found another post in the archives where Maxim D. said  
support was not available as of October 2009.

Build error --with-debug; ECDHE key exchange TLS problem.[nginx 0.7.62]

> **[Build error --with-debug; ECDHE key exchange TLS problem. \[nginx 0.7.62\]](https://forum.nginx.org/read.php?2,11737,11737)**
>
> nginx version: 0.7.62 OpenSSL version: 1.0.0-beta3 Platform: Linux 2.6.18 x64 \* Short description of problem: \* (a) nginx seems not to handle ephemeral DH key exchanges with EC. (kx=ECDHE, auth=ECDSA) Connection dies on handshake. (b) A build error...

–  
Calomel @ [https://calomel.org](https://calomel.org)  
Open Source Research and Reference

---

<div class="post-metadata">

**Author:** ![Calomel\_Org](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/59ef9b/32.png) [@Calomel\_Org](https://www.ruby-forum.com/u/Calomel_Org)\
**Post date:** [July 14, 2010, 8:14pm UTC](https://www.ruby-forum.com/t/ecdhe-key-exchange-with-tlsv1/191344/2 "2010-07-14T20:14:03Z")

</div>

I tried a few variations to get ECC keys working with Nginx. Most  
likely Nginx does not yet support ECC key exchanges yet.

Firefox, Chrome, Safari and IE8 do support ECC ciphers. The  
about:config in Firefox shows “security.ssl3.ecdhe\_ecdsa\_aes\_256\_sha”  
for example.

For future reference,

The build environment:  
Nginx v0.8.45 (built and linked against openssl v1.0.0.a)  
Openssl v1.0.0.a

The ECC ciphers are available according to the cipher list:  
openssl ciphers -tls1 -v ‘HIGH:!ADH:!MD5:@STRENGTH’ | grep 256 | grep  
ECDH  
ECDHE-RSA-AES256-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1  
ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1  
AECDH-AES256-SHA SSLv3 Kx=ECDH Au=None Enc=AES(256) Mac=SHA1  
ECDH-RSA-AES256-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA1  
ECDH-ECDSA-AES256-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA1

I am not sure if this is right format for Nginx and the ssl\_dhparam  
directive, but I was able to generate a ECC key using:  
openssl ecparam -genkey -name secp521r1 -out eckey.pem | /  
openssl ec -aes128 -out EC-newkey.pem

This is the s\_client test used from another machine also using openssl  
v1.0.0.a:  
openssl s\_client -connect [hostname.com:443](http://hostname.com:443) -cipher  
ECDHE-ECDSA-AES256-SHA

Anyone is interested in more information about ECC could start with,  
Elliptical Curves suggest the most modern concepts of cryptography  
[http://blog.taragana.com/index.php/archive/mathematical-theory-of-elliptic-curves-may-help-strengthen-it-security/](http://blog.taragana.com/index.php/archive/mathematical-theory-of-elliptic-curves-may-help-strengthen-it-security/)

If anyone sees a problem or has a solution to this setup please mail  
me. Igor, I would be happy to do any tests.

–  
Calomel @ [https://calomel.org](https://calomel.org)  
Open Source Research and Reference

---

<div class="post-metadata">

**Author:** ![Calomel\_Org](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/59ef9b/32.png) [@Calomel\_Org](https://www.ruby-forum.com/u/Calomel_Org)\
**Post date:** [July 15, 2010, 11:58am UTC](https://www.ruby-forum.com/t/ecdhe-key-exchange-with-tlsv1/191344/3 "2010-07-15T11:58:44Z")

</div>

Hello!

On Fri, Jul 09, 2010 at 04:03:55PM -0400, Calomel Org wrote:

> Does Nginx support the elliptic curve cryptography ciphers like  
> ECDHE-ECDSA-AES256-SHA available through OpenSSL v1.0.0a ?

No.

[…]

> Does “ssl\_dhparam” need a PEM string? Any examples?

It needs file name, but it’s for DH params, not ECDH.

> BTW, I found another post in the archives where Maxim D. said  
> support was not available as of October 2009.
> 
> Build error --with-debug; ECDHE key exchange TLS problem.[nginx 0.7.62]  
> [http://forum.nginx.org/read.php?2,11737,11737](http://forum.nginx.org/read.php?2,11737,11737)

This message still applies.

Maxim D.

---

<div class="post-metadata">

**Author:** ![Calomel\_Org](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/59ef9b/32.png) [@Calomel\_Org](https://www.ruby-forum.com/u/Calomel_Org)\
**Post date:** [January 5, 2011, 5:20am UTC](https://www.ruby-forum.com/t/ecdhe-key-exchange-with-tlsv1/191344/4 "2011-01-05T05:20:29Z")

</div>

Hello!

On Tue, Jan 04, 2011 at 10:34:07AM -0500, timo2 wrote:

> I was able to add support for elliptic curve cryptography. Nginx has to  
> be compiled with Openssl 1.0.0 libraries, though. The patch against  
> nginx-0.8.54 is here (sorry I do not know how to add attachment).

You may want to use nginx-devel@ (cc’d) mailing list instead, and  
use latest development version (0.9.3) for patches (it’s very  
close, but just to be sure).

Most serious problem with the patch is it won’t compile with older  
OpenSSL versions: nginx is currently expected to compile with  
OpenSSL 0.9.7+.

As this patch uses OpenSSL 1.0.0+ only functions / data types - it  
should be guarded with appropriate preprocessor / configure  
checks.

Some minor problems are noted below.

> Basicly, it ads extra configuration parameter ssl\_eccurve with  
> which one can specify the elliptic curve. If this parameter is  
> missing then the default secp224r1 curve is used.

It looks like OpenSSL’s s\_server as well as Apache defaults to  
nistp256 aka secp256r1. Any specific reasons for secp224r1?

> +ngx\_int\_t  
> +ngx\_ssl\_eccurve(ngx\_conf\_t \*cf, ngx\_ssl\_t \*ssl, ngx\_str\_t  
> \*named\_curve)

Using “name” instead of “named\_curve” probably would be better  
here.

> - 
> - EC\_KEY \*ecdh=NULL;

Any reason why this should be initialized to NULL?.. (1)

> - int nid;
> - 
> - if (named\_curve-\>len) {

It’s probably good idea to reverse this check to be in line with  
ngx\_ssl\_dhparam().

> - 
> 
> ```
> nid = OBJ_sn2nid( (const char *) named_curve->data);
> 
> ```

Casting to “const” isn’t needed, only to “char \*”. Using space in  
“( (” isn’t needed as well (style).

> - 
> - 
> 
> ```
> if (nid == 0) {
> 
> ```
> 
> - 
> 
> ```
> ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "Unknown curve
> 
> ```
> 
> name (%s)\n", named\_curve-\>data);

No need to use “\n”. Applies to other places as well.

> - 
> - 
> 
> ```
> EC_KEY_free(ecdh);
> 
> ```

(1) … and this call EC\_KEY\_free(), while we are perfectly sure  
we don’t have anything usefull in ecdh?

> - 
> 
> ```
> return NGX_ERROR;
> 
> ```
> 
> - 
> 
> ```
> }
> 
> ```
> 
> - 
> - 
> 
> ```
> ecdh = EC_KEY_new_by_curve_name(nid);
> 
> ```
> 
> - 
> - 
> 
> ```
> if (ecdh == NULL) {
> 
> ```
> 
> - 
> 
> ```
> ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "Unable to create
> 
> ```
> 
> curve (%s)\n", named\_curve-\>data);  
> +
> 
> - 
> 
> ```
> EC_KEY_free(ecdh);
> 
> ```

The same here. We know for sure ecdh is NULL.

> - ecdh = EC\_KEY\_new\_by\_curve\_name(NID\_secp224r1);
> - 
> - if (ecdh == NULL) {
> - 
> 
> ```
> ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "Unable to create
> 
> ```
> 
> curve (%s)\n", named\_curve-\>data);  
> +
> 
> - 
> 
> ```
> EC_KEY_free(ecdh);
> 
> ```

And here.

> ## ngx\_int\_t ngx\_int\_t ngx\_ssl\_generate\_rsa512\_key(ngx\_ssl\_t \*ssl); nginx-0.8.54p/src/http/modules/ngx\_http\_ssl\_module.c — nginx-0.8.54/src/http/modules/ngx\_http\_ssl\_module.c 2010-05-14 12:56:37.000000000 +0300 +++ nginx-0.8.54p/src/http/modules/ngx\_http\_ssl\_module.c 2011-01-04 16:06:10.000000000 +0200 @@ -77,7 +77,14 @@ static ngx\_command\_t ngx\_http\_ssl\_comma NGX\_HTTP\_SRV\_CONF\_OFFSET, offsetof(ngx\_http\_ssl\_srv\_conf\_t, dhparam), NULL },
> 
> -

Unrelated whitespace change.

> - { ngx\_string(“ssl\_eccurve”),
> - 
> 
> ```
> NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
> 
> ```
> 
> - 
> 
> ```
> ngx_conf_set_str_slot,
> 
> ```
> 
> - 
> 
> ```
> NGX_HTTP_SRV_CONF_OFFSET,
> 
> ```
> 
> - 
> 
> ```
> offsetof(ngx_http_ssl_srv_conf_t, eccurve),
> 
> ```
> 
> - 
> 
> ```
> NULL },
> 
> ```
> 
> -

Trailing spaces.

> ```
> * sscf->ciphers = { 0, NULL };
> 
> ```
> 
> @@ -473,6 +483,10 @@ ngx\_http\_ssl\_merge\_srv\_conf(ngx\_conf\_t \*
> 
> - ngx\_str\_t eccurve;  
> offsetof(ngx\_mail\_ssl\_conf\_t, dhparam),  
> NULL },
> 
> - { ngx\_string(“ssl\_eccurve”),
> 
> - 
> 
> ```
> NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
> 
> ```
> 
> - 
> 
> ```
> ngx_conf_set_str_slot,
> 
> ```
> 
> - 
> 
> ```
> NGX_MAIL_SRV_CONF_OFFSET,
> 
> ```
> 
> - 
> 
> ```
> offsetof(ngx_mail_ssl_conf_t, eccurve),
> 
> ```
> 
> - 
> 
> ```
> NULL },
> 
> ```
> 
> -

Trailing spaces.

> ```
> */
> 
> ```
> 
> @@ -294,6 +304,10 @@ ngx\_mail\_ssl\_merge\_conf(ngx\_conf\_t \*cf,
> 
> - ngx\_str\_t eccurve;

Otherwise looks good, thank you for your patch. Please resubmit  
with fixes to nginx-devel@.

Maxim D.

---

<div class="post-metadata">

**Author:** ![Calomel\_Org](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/59ef9b/32.png) [@Calomel\_Org](https://www.ruby-forum.com/u/Calomel_Org)\
**Post date:** [January 4, 2011, 4:36pm UTC](https://www.ruby-forum.com/t/ecdhe-key-exchange-with-tlsv1/191344/5 "2011-01-04T16:36:01Z")

</div>

Hi,

I was able to add support for elliptic curve cryptography. Nginx has to  
be compiled with Openssl 1.0.0 libraries, though. The patch against  
nginx-0.8.54 is here (sorry I do not know how to add attachment).  
Basicly, it ads extra configuration parameter ssl\_eccurve with which one  
can specify the elliptic curve. If this parameter is missing then the  
default secp224r1 curve is used.

```auto
diff -rupN nginx-0.8.54/src/event/ngx_event_openssl.c
nginx-0.8.54p/src/event/ngx_event_openssl.c
--- nginx-0.8.54/src/event/ngx_event_openssl.c 2010-07-29
12:30:15.000000000 +0300
+++ nginx-0.8.54p/src/event/ngx_event_openssl.c 2011-01-04
17:11:08.000000000 +0200
@@ -479,6 +479,60 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_
     return NGX_OK;
 }

+ngx_int_t
+ngx_ssl_eccurve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t
*named_curve)
+{
+ /*
+ * Elliptic-Curve Diffie-Hellman parameters are either "named
curves"
+ * from RFC 4492 section 5.1.1, or explicitly described curves
over
+ * binary fields. OpenSSL only supports the "named curves", which
provide
+ * maximum interoperability.
+ */
+
+ EC_KEY *ecdh=NULL;
+ int nid;
+
+ if (named_curve->len) {
+ nid = OBJ_sn2nid( (const char *) named_curve->data);
+
+ if (nid == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "Unknown curve
name (%s)\n", named_curve->data);
+
+ EC_KEY_free(ecdh);
+ return NGX_ERROR;
+ }
+
+ ecdh = EC_KEY_new_by_curve_name(nid);
+
+ if (ecdh == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "Unable to create
curve (%s)\n", named_curve->data);
+
+ EC_KEY_free(ecdh);
+ return NGX_ERROR;
+ }
+
+ SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
+
+ EC_KEY_free(ecdh);
+
+ return NGX_OK;
+ }
+
+ ecdh = EC_KEY_new_by_curve_name(NID_secp224r1);
+
+ if (ecdh == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "Unable to create
curve (%s)\n", named_curve->data);
+
+ EC_KEY_free(ecdh);
+ return NGX_ERROR;
+ }
+
+ SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
+
+ EC_KEY_free(ecdh);
+
+ return NGX_OK;
+}

 ngx_int_t
 ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
ngx_uint_t flags)
diff -rupN nginx-0.8.54/src/event/ngx_event_openssl.h
nginx-0.8.54p/src/event/ngx_event_openssl.h
--- nginx-0.8.54/src/event/ngx_event_openssl.h 2010-03-03
18:23:14.000000000 +0200
+++ nginx-0.8.54p/src/event/ngx_event_openssl.h 2011-01-04
14:57:00.000000000 +0200
@@ -101,6 +101,7 @@ ngx_int_t ngx_ssl_client_certificate(ngx
 ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
 ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl);
 ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t
*file);
+ngx_int_t ngx_ssl_eccurve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t
*named_curve);
 ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
     ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t
timeout);
 ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t
*c,
diff -rupN nginx-0.8.54/src/http/modules/ngx_http_ssl_module.c
nginx-0.8.54p/src/http/modules/ngx_http_ssl_module.c
--- nginx-0.8.54/src/http/modules/ngx_http_ssl_module.c 2010-05-14
12:56:37.000000000 +0300
+++ nginx-0.8.54p/src/http/modules/ngx_http_ssl_module.c 2011-01-04
16:06:10.000000000 +0200
@@ -77,7 +77,14 @@ static ngx_command_t ngx_http_ssl_comma
       NGX_HTTP_SRV_CONF_OFFSET,
       offsetof(ngx_http_ssl_srv_conf_t, dhparam),
       NULL },
-
+
+ { ngx_string("ssl_eccurve"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_ssl_srv_conf_t, eccurve),
+ NULL },
+
     { ngx_string("ssl_protocols"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
       ngx_conf_set_bitmask_slot,
@@ -312,6 +319,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t
      * sscf->certificate = { 0, NULL };
      * sscf->certificate_key = { 0, NULL };
      * sscf->dhparam = { 0, NULL };
+ * sscf->eccurve = { 0, NULL };
      * sscf->client_certificate = { 0, NULL };
      * sscf->crl = { 0, NULL };
      * sscf->ciphers = { 0, NULL };
@@ -356,6 +364,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *

     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");

+ ngx_conf_merge_str_value(conf->eccurve, prev->eccurve, "");
+
     ngx_conf_merge_str_value(conf->client_certificate,
prev->client_certificate,
                          "");
     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
@@ -473,6 +483,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
         return NGX_CONF_ERROR;
     }

+ if (ngx_ssl_eccurve(cf, &conf->ssl, &conf->eccurve) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
     ngx_conf_merge_value(conf->builtin_session_cache,
                          prev->builtin_session_cache,
NGX_SSL_NONE_SCACHE);

diff -rupN nginx-0.8.54/src/http/modules/ngx_http_ssl_module.h
nginx-0.8.54p/src/http/modules/ngx_http_ssl_module.h
--- nginx-0.8.54/src/http/modules/ngx_http_ssl_module.h 2009-07-23
15:21:26.000000000 +0300
+++ nginx-0.8.54p/src/http/modules/ngx_http_ssl_module.h 2011-01-04
15:41:00.000000000 +0200
@@ -32,6 +32,7 @@ typedef struct {
     ngx_str_t certificate;
     ngx_str_t certificate_key;
     ngx_str_t dhparam;
+ ngx_str_t eccurve;
     ngx_str_t client_certificate;
     ngx_str_t crl;

diff -rupN nginx-0.8.54/src/mail/ngx_mail_ssl_module.c
nginx-0.8.54p/src/mail/ngx_mail_ssl_module.c
--- nginx-0.8.54/src/mail/ngx_mail_ssl_module.c 2010-05-14
12:56:37.000000000 +0300
+++ nginx-0.8.54p/src/mail/ngx_mail_ssl_module.c 2011-01-04
14:55:00.000000000 +0200
@@ -77,6 +77,13 @@ static ngx_command_t ngx_mail_ssl_comma
       offsetof(ngx_mail_ssl_conf_t, dhparam),
       NULL },

+ { ngx_string("ssl_eccurve"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_MAIL_SRV_CONF_OFFSET,
+ offsetof(ngx_mail_ssl_conf_t, eccurve),
+ NULL },
+
     { ngx_string("ssl_protocols"),
       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
       ngx_conf_set_bitmask_slot,
@@ -163,6 +170,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
      * scf->certificate = { 0, NULL };
      * scf->certificate_key = { 0, NULL };
      * scf->dhparam = { 0, NULL };
+ * scf->eccurve = { 0, NULL };
      * scf->ciphers = { 0, NULL };
      * scf->shm_zone = NULL;
      */
@@ -204,6 +212,8 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf,

     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");

+ ngx_conf_merge_str_value(conf->eccurve, prev->eccurve, "");
+
     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers,
NGX_DEFAULT_CIPHERS);

@@ -294,6 +304,10 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf,
         return NGX_CONF_ERROR;
     }

+ if (ngx_ssl_eccurve(cf, &conf->ssl, &conf->eccurve) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
     ngx_conf_merge_value(conf->builtin_session_cache,
                          prev->builtin_session_cache,
NGX_SSL_NONE_SCACHE);

diff -rupN nginx-0.8.54/src/mail/ngx_mail_ssl_module.h
nginx-0.8.54p/src/mail/ngx_mail_ssl_module.h
--- nginx-0.8.54/src/mail/ngx_mail_ssl_module.h 2008-09-01
17:19:01.000000000 +0300
+++ nginx-0.8.54p/src/mail/ngx_mail_ssl_module.h 2011-01-04
14:49:00.000000000 +0200
@@ -34,6 +34,7 @@ typedef struct {
     ngx_str_t certificate;
     ngx_str_t certificate_key;
     ngx_str_t dhparam;
+ ngx_str_t eccurve;

     ngx_str_t ciphers;

```

Posted at Nginx Forum:

> **[Re: ECDHE key exchange with TLSv1](https://forum.nginx.org/read.php?2,107166,163401#msg-163401)**
>
> Does Nginx support the elliptic curve cryptography ciphers like ECDHE-ECDSA-AES256-SHA available through OpenSSL v1.0.0a ? I have built OpenSSL v1.0.0a and placed it in a separate directory. I then built nginx with --with-cc-opt="-I...

---

<div class="post-metadata">

**Author:** ![Calomel\_Org](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/59ef9b/32.png) [@Calomel\_Org](https://www.ruby-forum.com/u/Calomel_Org)\
**Post date:** [January 5, 2011, 10:57pm UTC](https://www.ruby-forum.com/t/ecdhe-key-exchange-with-tlsv1/191344/6 "2011-01-05T22:57:03Z")

</div>

Hello,

Updated patch

```auto
diff -rupN nginx-0.9.3/src/event/ngx_event_openssl.c
nginx-0.9.3p/src/event/ngx_event_openssl.c
--- nginx-0.9.3/src/event/ngx_event_openssl.c 2011-01-05
20:38:18.000000000 +0200
+++ nginx-0.9.3p/src/event/ngx_event_openssl.c 2011-01-05
20:33:55.000000000 +0200
@@ -478,6 +478,42 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_
     return NGX_OK;
 }

+ngx_int_t
+ngx_ssl_eccurve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
+#ifndef OPENSSL_NO_ECDH
+ EC_KEY *ecdh;
+ int nid;
+
+ /*
+ * Elliptic-Curve Diffie-Hellman parameters are either "named
curves"
+ * from RFC 4492 section 5.1.1, or explicitely described curves
over
+ * binary fields. OpenSSL only supports the "named curves", which
provide
+ * maximum interoperability.
+ */
+
+ nid = OBJ_sn2nid((const char *)name->data);
+ if (nid == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "Unknown curve name (%s)", name->data);
+ return NGX_ERROR;
+ }
+
+ ecdh = EC_KEY_new_by_curve_name(nid);
+ if (ecdh == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "Unable to create curve (%s)", name->data);
+ return NGX_ERROR;
+ }
+
+ SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
+
+ EC_KEY_free(ecdh);
+#endif
+#endif
+ return NGX_OK;
+}

 ngx_int_t
 ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
ngx_uint_t flags)
diff -rupN nginx-0.9.3/src/event/ngx_event_openssl.h
nginx-0.9.3p/src/event/ngx_event_openssl.h
--- nginx-0.9.3/src/event/ngx_event_openssl.h 2011-01-05
20:38:16.000000000 +0200
+++ nginx-0.9.3p/src/event/ngx_event_openssl.h 2011-01-05
20:33:53.000000000 +0200
@@ -101,6 +101,7 @@ ngx_int_t ngx_ssl_client_certificate(ngx
 ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
 ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl);
 ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t
*file);
+ngx_int_t ngx_ssl_eccurve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t
*name);
 ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
     ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t
timeout);
 ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t
*c,
diff -rupN nginx-0.9.3/src/http/modules/ngx_http_ssl_module.c
nginx-0.9.3p/src/http/modules/ngx_http_ssl_module.c
--- nginx-0.9.3/src/http/modules/ngx_http_ssl_module.c 2011-01-05
20:38:28.000000000 +0200
+++ nginx-0.9.3p/src/http/modules/ngx_http_ssl_module.c 2011-01-05
21:15:29.000000000 +0200
@@ -14,7 +14,7 @@ typedef ngx_int_t (*ngx_ssl_variable_han

 #define NGX_DEFAULT_CIPHERS "HIGH:!ADH:!MD5"
-
+#define NGX_DEFAULT_ECCURVE "prime256v1"

 static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
@@ -78,6 +78,13 @@ static ngx_command_t ngx_http_ssl_comma
       offsetof(ngx_http_ssl_srv_conf_t, dhparam),
       NULL },

+ { ngx_string("ssl_eccurve"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_ssl_srv_conf_t, eccurve),
+ NULL },
+
     { ngx_string("ssl_protocols"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
       ngx_conf_set_bitmask_slot,
@@ -312,6 +319,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t
      * sscf->certificate = { 0, NULL };
      * sscf->certificate_key = { 0, NULL };
      * sscf->dhparam = { 0, NULL };
+ * sscf->eccurve = { 0, NULL };
      * sscf->client_certificate = { 0, NULL };
      * sscf->crl = { 0, NULL };
      * sscf->ciphers = { 0, NULL };
@@ -360,6 +368,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
                          "");
     ngx_conf_merge_str_value(conf->crl, prev->crl, "");

+ ngx_conf_merge_str_value(conf->eccurve, prev->eccurve,
NGX_DEFAULT_ECCURVE);
+
     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers,
NGX_DEFAULT_CIPHERS);

@@ -473,6 +483,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
         return NGX_CONF_ERROR;
     }

+ if (ngx_ssl_eccurve(cf, &conf->ssl, &conf->eccurve) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
     ngx_conf_merge_value(conf->builtin_session_cache,
                          prev->builtin_session_cache,
NGX_SSL_NONE_SCACHE);

diff -rupN nginx-0.9.3/src/http/modules/ngx_http_ssl_module.h
nginx-0.9.3p/src/http/modules/ngx_http_ssl_module.h
--- nginx-0.9.3/src/http/modules/ngx_http_ssl_module.h 2011-01-05
20:38:37.000000000 +0200
+++ nginx-0.9.3p/src/http/modules/ngx_http_ssl_module.h 2011-01-05
20:34:16.000000000 +0200
@@ -32,6 +32,7 @@ typedef struct {
     ngx_str_t certificate;
     ngx_str_t certificate_key;
     ngx_str_t dhparam;
+ ngx_str_t eccurve;
     ngx_str_t client_certificate;
     ngx_str_t crl;

diff -rupN nginx-0.9.3/src/mail/ngx_mail_ssl_module.c
nginx-0.9.3p/src/mail/ngx_mail_ssl_module.c
--- nginx-0.9.3/src/mail/ngx_mail_ssl_module.c 2011-01-05
20:37:52.000000000 +0200
+++ nginx-0.9.3p/src/mail/ngx_mail_ssl_module.c 2011-01-05
20:33:43.000000000 +0200
@@ -10,7 +10,7 @@

 #define NGX_DEFAULT_CIPHERS "HIGH:!ADH:!MD5"
-
+#define NGX_DEFAULT_ECCURVE "prime256v1"

 static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf);
 static char *ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void
*child);
@@ -77,6 +77,13 @@ static ngx_command_t ngx_mail_ssl_comma
       offsetof(ngx_mail_ssl_conf_t, dhparam),
       NULL },

+ { ngx_string("ssl_eccurve"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_MAIL_SRV_CONF_OFFSET,
+ offsetof(ngx_mail_ssl_conf_t, eccurve),
+ NULL },
+
     { ngx_string("ssl_protocols"),
       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
       ngx_conf_set_bitmask_slot,
@@ -163,6 +170,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
      * scf->certificate = { 0, NULL };
      * scf->certificate_key = { 0, NULL };
      * scf->dhparam = { 0, NULL };
+ * scf->eccurve = { 0, NULL };
      * scf->ciphers = { 0, NULL };
      * scf->shm_zone = NULL;
      */
@@ -204,6 +212,8 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf,

     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");

+ ngx_conf_merge_str_value(conf->eccurve, prev->eccurve,
NGX_DEFAULT_ECCURVE);
+
     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers,
NGX_DEFAULT_CIPHERS);

diff -rupN nginx-0.9.3/src/mail/ngx_mail_ssl_module.h
nginx-0.9.3p/src/mail/ngx_mail_ssl_module.h
--- nginx-0.9.3/src/mail/ngx_mail_ssl_module.h 2011-01-05
20:37:52.000000000 +0200
+++ nginx-0.9.3p/src/mail/ngx_mail_ssl_module.h 2011-01-05
20:33:43.000000000 +0200
@@ -34,6 +34,7 @@ typedef struct {
     ngx_str_t certificate;
     ngx_str_t certificate_key;
     ngx_str_t dhparam;
+ ngx_str_t eccurve;

     ngx_str_t ciphers;

```

Topic continues in [Re: ECDHE key exchange with TLSv1](http://forum.nginx.org/read.php?29,163903)

Posted at Nginx Forum:

> **[Re: ECDHE key exchange with TLSv1](https://forum.nginx.org/read.php?2,107166,163911#msg-163911)**
>
> Does Nginx support the elliptic curve cryptography ciphers like ECDHE-ECDSA-AES256-SHA available through OpenSSL v1.0.0a ? I have built OpenSSL v1.0.0a and placed it in a separate directory. I then built nginx with --with-cc-opt="-I...
