2626 */
2727#include "private-lib-core.h"
2828#include "private-lib-tls-openssl.h"
29+ #if defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
30+ #include <openssl/core_names.h>
31+ #include <openssl/param_build.h>
32+ #endif
2933
3034#if !defined(OPENSSL_NO_EC ) && defined(LWS_HAVE_EC_KEY_new_by_curve_name ) && \
3135 (OPENSSL_VERSION_NUMBER >= 0x30000000l ) && \
@@ -118,24 +122,45 @@ const struct lws_ec_curves lws_ec_curves[4] = {
118122};
119123
120124static int
121- lws_genec_eckey_import (int nid , EVP_PKEY * pkey ,
125+ lws_genec_eckey_import (int nid , EVP_PKEY * * pkey ,
122126 const struct lws_gencrypto_keyelem * el )
123127{
128+ #if defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
129+ OSSL_PARAM params [5 ];
130+ int pidx = 0 ;
131+ EVP_PKEY_CTX * pctx ;
132+ EVP_PKEY * tmp_pkey = NULL ;
133+ const char * cname = OBJ_nid2sn (nid );
134+
135+ if (!cname ) return -1 ;
136+ params [pidx ++ ] = OSSL_PARAM_construct_utf8_string ("group" , (char * )cname , 0 );
137+ if (el [LWS_GENCRYPTO_EC_KEYEL_X ].buf )
138+ params [pidx ++ ] = OSSL_PARAM_construct_BN ("qx" , (unsigned char * )el [LWS_GENCRYPTO_EC_KEYEL_X ].buf , el [LWS_GENCRYPTO_EC_KEYEL_X ].len );
139+ if (el [LWS_GENCRYPTO_EC_KEYEL_Y ].buf )
140+ params [pidx ++ ] = OSSL_PARAM_construct_BN ("qy" , (unsigned char * )el [LWS_GENCRYPTO_EC_KEYEL_Y ].buf , el [LWS_GENCRYPTO_EC_KEYEL_Y ].len );
141+ if (el [LWS_GENCRYPTO_EC_KEYEL_D ].buf && el [LWS_GENCRYPTO_EC_KEYEL_D ].len )
142+ params [pidx ++ ] = OSSL_PARAM_construct_BN ("priv" , (unsigned char * )el [LWS_GENCRYPTO_EC_KEYEL_D ].buf , el [LWS_GENCRYPTO_EC_KEYEL_D ].len );
143+ params [pidx ] = OSSL_PARAM_construct_end ();
144+
145+ pctx = EVP_PKEY_CTX_new_from_name (NULL , "EC" , NULL );
146+ if (!pctx ) return -1 ;
147+ if (EVP_PKEY_fromdata_init (pctx ) <= 0 ||
148+ EVP_PKEY_fromdata (pctx , & tmp_pkey , EVP_PKEY_KEYPAIR , params ) <= 0 ) {
149+ EVP_PKEY_CTX_free (pctx );
150+ return -1 ;
151+ }
152+ EVP_PKEY_CTX_free (pctx );
153+
154+ * pkey = tmp_pkey ;
155+ return 0 ;
156+ #else
124157 EC_KEY * ec = EC_KEY_new_by_curve_name (nid );
125158 BIGNUM * bn_d , * bn_x , * bn_y ;
126159 int n ;
127160
128161 if (!ec )
129162 return -1 ;
130163
131- /*
132- * EC_KEY contains
133- *
134- * EC_GROUP * group
135- * EC_POINT * pub_key
136- * BIGNUM * priv_key (ie, d)
137- */
138-
139164 bn_x = BN_bin2bn (el [LWS_GENCRYPTO_EC_KEYEL_X ].buf ,
140165 SSL_SIZE_T_CAST (el [LWS_GENCRYPTO_EC_KEYEL_X ].len ), NULL );
141166 if (!bn_x ) {
@@ -149,14 +174,6 @@ lws_genec_eckey_import(int nid, EVP_PKEY *pkey,
149174 goto bail1 ;
150175 }
151176
152- /*
153- * EC_KEY_set_public_key_affine_coordinates sets the public key for
154- * key based on its affine co-ordinates, i.e. it constructs an
155- * EC_POINT object based on the supplied x and y values and sets
156- * the public key to be this EC_POINT. It will also performs
157- * certain sanity checks on the key to confirm that it is valid.
158- */
159-
160177#if defined(USE_WOLFSSL )
161178 n = wolfSSL_EC_POINT_set_affine_coordinates_GFp (ec -> group ,
162179 ec -> pub_key ,
@@ -190,18 +207,21 @@ lws_genec_eckey_import(int nid, EVP_PKEY *pkey,
190207 }
191208 }
192209
193- /* explicitly confirm the key pieces are consistent */
194-
195210#if !defined(USE_WOLFSSL )
196211 if (EC_KEY_check_key (ec ) != 1 ) {
197212 lwsl_err ("%s: EC_KEY_set_private_key fail\n" , __func__ );
198213 goto bail ;
199214 }
200215#endif
201216
202- n = EVP_PKEY_assign_EC_KEY (pkey , ec );
217+ * pkey = EVP_PKEY_new ();
218+ if (!* pkey ) goto bail ;
219+
220+ n = EVP_PKEY_assign_EC_KEY (* pkey , ec );
203221 if (n != 1 ) {
204222 lwsl_err ("%s: EVP_PKEY_set1_EC_KEY failed\n" , __func__ );
223+ EVP_PKEY_free (* pkey );
224+ * pkey = NULL ;
205225 return -1 ;
206226 }
207227
@@ -213,6 +233,7 @@ lws_genec_eckey_import(int nid, EVP_PKEY *pkey,
213233 EC_KEY_free (ec );
214234
215235 return -1 ;
236+ #endif
216237}
217238
218239static int
@@ -240,11 +261,7 @@ lws_genec_keypair_import(struct lws_genec_ctx *ctx,
240261
241262 ctx -> has_private = !!el [LWS_GENCRYPTO_EC_KEYEL_D ].len ;
242263
243- pkey = EVP_PKEY_new ();
244- if (!pkey )
245- return -7 ;
246-
247- if (lws_genec_eckey_import (curve -> tls_lib_nid , pkey , el )) {
264+ if (lws_genec_eckey_import (curve -> tls_lib_nid , & pkey , el )) {
248265 lwsl_err ("%s: lws_genec_eckey_import fail\n" , __func__ );
249266 goto bail ;
250267 }
@@ -359,6 +376,58 @@ lws_genec_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
359376 return -22 ;
360377 }
361378
379+ #if defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
380+ pkey = EVP_PKEY_Q_keygen (NULL , NULL , "EC" , curve_name );
381+ if (!pkey ) goto bail ;
382+
383+ ctx -> ctx [side ] = EVP_PKEY_CTX_new (pkey , NULL );
384+ if (!ctx -> ctx [side ]) goto bail1 ;
385+
386+ if (!EVP_PKEY_get_bn_param (pkey , "qx" , & bn_x ) ||
387+ !EVP_PKEY_get_bn_param (pkey , "qy" , & bn_y )) {
388+ goto bail2 ;
389+ }
390+
391+ cbn [0 ] = bn_x ;
392+ if (!EVP_PKEY_get_bn_param (pkey , "priv" , (BIGNUM * * )& cbn [1 ])) {
393+ goto bail2 ;
394+ }
395+ cbn [2 ] = bn_y ;
396+
397+ el [LWS_GENCRYPTO_EC_KEYEL_CRV ].len = (uint32_t )strlen (curve_name ) + 1 ;
398+ el [LWS_GENCRYPTO_EC_KEYEL_CRV ].buf =
399+ lws_malloc (el [LWS_GENCRYPTO_EC_KEYEL_CRV ].len , "ec" );
400+ if (!el [LWS_GENCRYPTO_EC_KEYEL_CRV ].buf ) {
401+ lwsl_err ("%s: OOM\n" , __func__ );
402+ goto bail2 ;
403+ }
404+
405+ strcpy ((char * )el [LWS_GENCRYPTO_EC_KEYEL_CRV ].buf , curve_name );
406+
407+ for (n = LWS_GENCRYPTO_EC_KEYEL_X ; n < LWS_GENCRYPTO_EC_KEYEL_COUNT ;
408+ n ++ ) {
409+ el [n ].len = curve -> key_bytes ;
410+ el [n ].buf = lws_malloc (curve -> key_bytes , "ec" );
411+ if (!el [n ].buf )
412+ goto bail2 ;
413+
414+ m = BN_bn2binpad (cbn [n - 1 ], el [n ].buf , (int32_t )el [n ].len );
415+ if ((uint32_t )m != el [n ].len )
416+ goto bail2 ;
417+ }
418+
419+ ctx -> has_private = 1 ;
420+
421+ ret = 0 ;
422+
423+ bail2 :
424+ BN_clear_free (bn_x );
425+ BN_clear_free (bn_y );
426+ if (cbn [1 ]) BN_clear_free ((BIGNUM * )cbn [1 ]);
427+ bail1 :
428+ EVP_PKEY_free (pkey );
429+ bail :
430+ #else
362431 ec = EC_KEY_new_by_curve_name (curve -> tls_lib_nid );
363432 if (!ec ) {
364433 lwsl_err ("%s: unknown nid %d\n" , __func__ , curve -> tls_lib_nid );
@@ -447,6 +516,7 @@ lws_genec_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
447516 EVP_PKEY_free (pkey );
448517bail :
449518 EC_KEY_free (ec );
519+ #endif
450520
451521 return ret ;
452522}
@@ -544,8 +614,6 @@ lws_genecdsa_hash_sign_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
544614 return -1 ;
545615 }
546616
547- eckey = EVP_PKEY_get1_EC_KEY (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]));
548-
549617 /*
550618 * The ECDSA P-256 SHA-256 digital signature is generated as follows:
551619 *
@@ -565,8 +633,39 @@ lws_genecdsa_hash_sign_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
565633 * 4. The resulting 64-octet sequence is the JWS Signature value.
566634 */
567635
636+ #if defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
637+ {
638+ EVP_PKEY_CTX * sctx ;
639+ unsigned char der_sig [256 ];
640+ size_t der_sig_len = sizeof (der_sig );
641+ const unsigned char * p = der_sig ;
642+
643+ sctx = EVP_PKEY_CTX_new (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]), NULL );
644+ if (!sctx ) {
645+ lwsl_notice ("%s: EVP_PKEY_CTX_new fail\n" , __func__ );
646+ goto bail ;
647+ }
648+
649+ if (EVP_PKEY_sign_init (sctx ) <= 0 ) {
650+ lwsl_notice ("%s: EVP_PKEY_sign_init fail\n" , __func__ );
651+ EVP_PKEY_CTX_free (sctx );
652+ goto bail ;
653+ }
654+
655+ if (EVP_PKEY_sign (sctx , der_sig , & der_sig_len , in , hs ) <= 0 ) {
656+ lwsl_notice ("%s: EVP_PKEY_sign fail\n" , __func__ );
657+ EVP_PKEY_CTX_free (sctx );
658+ goto bail ;
659+ }
660+ EVP_PKEY_CTX_free (sctx );
661+
662+ ecdsasig = d2i_ECDSA_SIG (NULL , & p , (long )der_sig_len );
663+ }
664+ #else
665+ eckey = EVP_PKEY_get1_EC_KEY (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]));
568666 ecdsasig = ECDSA_do_sign (in , SSL_SIZE_T_CAST (hs ), eckey );
569667 EC_KEY_free (eckey );
668+ #endif
570669 if (!ecdsasig ) {
571670 lwsl_notice ("%s: ECDSA_do_sign fail\n" , __func__ );
572671 goto bail ;
@@ -655,10 +754,44 @@ lws_genecdsa_hash_sig_verify_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
655754 goto bail1 ;
656755 }
657756
658- eckey = EVP_PKEY_get1_EC_KEY (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]));
757+ #if defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
758+ {
759+ unsigned char * der = NULL ;
760+ int der_len ;
761+ EVP_PKEY_CTX * vctx ;
659762
763+ der_len = i2d_ECDSA_SIG (ecsig , & der );
764+ if (der_len <= 0 ) {
765+ n = -1 ;
766+ goto v_bail ;
767+ }
768+
769+ vctx = EVP_PKEY_CTX_new (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]), NULL );
770+ if (!vctx ) {
771+ OPENSSL_free (der );
772+ n = -1 ;
773+ goto v_bail ;
774+ }
775+
776+ if (EVP_PKEY_verify_init (vctx ) <= 0 ) {
777+ EVP_PKEY_CTX_free (vctx );
778+ OPENSSL_free (der );
779+ n = -1 ;
780+ goto v_bail ;
781+ }
782+
783+ n = EVP_PKEY_verify (vctx , der , (size_t )der_len , in , (size_t )hlen );
784+ EVP_PKEY_CTX_free (vctx );
785+ OPENSSL_free (der );
786+ v_bail :
787+ ;
788+ }
789+ #else
790+ eckey = EVP_PKEY_get1_EC_KEY (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]));
660791 n = ECDSA_do_verify (in , SSL_SIZE_T_CAST (hlen ), ecsig , eckey );
661792 EC_KEY_free (eckey );
793+ #endif
794+
662795 if (n != 1 ) {
663796 unsigned long err = ERR_get_error ();
664797 char buf [256 ];
@@ -696,6 +829,34 @@ lws_genecdh_compute_shared_secret(struct lws_genec_ctx *ctx, uint8_t *ss,
696829 return -1 ;
697830 }
698831
832+ #if defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
833+ {
834+ EVP_PKEY_CTX * dctx ;
835+ size_t slen = (size_t )* ss_len ;
836+
837+ dctx = EVP_PKEY_CTX_new (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [LDHS_OURS ]), NULL );
838+ if (!dctx )
839+ return -1 ;
840+
841+ if (EVP_PKEY_derive_init (dctx ) <= 0 ) {
842+ EVP_PKEY_CTX_free (dctx );
843+ return -1 ;
844+ }
845+ if (EVP_PKEY_derive_set_peer (dctx , EVP_PKEY_CTX_get0_pkey (ctx -> ctx [LDHS_THEIRS ])) <= 0 ) {
846+ EVP_PKEY_CTX_free (dctx );
847+ return -1 ;
848+ }
849+
850+ if (EVP_PKEY_derive (dctx , ss , & slen ) <= 0 ) {
851+ EVP_PKEY_CTX_free (dctx );
852+ return -1 ;
853+ }
854+
855+ * ss_len = (int )slen ;
856+ ret = 0 ;
857+ EVP_PKEY_CTX_free (dctx );
858+ }
859+ #else
699860 eckey [LDHS_OURS ] = EVP_PKEY_get1_EC_KEY (
700861 EVP_PKEY_CTX_get0_pkey (ctx -> ctx [LDHS_OURS ]));
701862 eckey [LDHS_THEIRS ] = EVP_PKEY_get1_EC_KEY (
@@ -721,6 +882,7 @@ lws_genecdh_compute_shared_secret(struct lws_genec_ctx *ctx, uint8_t *ss,
721882
722883 EC_KEY_free (eckey [LDHS_OURS ]);
723884 EC_KEY_free (eckey [LDHS_THEIRS ]);
885+ #endif
724886
725887 return ret ;
726888}
0 commit comments