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 }
@@ -344,12 +361,16 @@ lws_genec_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
344361 const char * curve_name , struct lws_gencrypto_keyelem * el )
345362{
346363 const struct lws_ec_curves * curve ;
364+ #if !defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
347365 const EC_POINT * pubkey ;
366+ #endif
348367 EVP_PKEY * pkey = NULL ;
349368 int ret = -29 , n , m ;
350369 BIGNUM * bn_x = NULL , * bn_y = NULL ;
351370 const BIGNUM * cbn [3 ];
371+ #if !defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
352372 EC_KEY * ec ;
373+ #endif
353374
354375 curve = lws_genec_curve (ctx -> curve_table , curve_name );
355376 if (!curve ) {
@@ -359,6 +380,58 @@ lws_genec_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
359380 return -22 ;
360381 }
361382
383+ #if defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
384+ pkey = EVP_PKEY_Q_keygen (NULL , NULL , "EC" , curve_name );
385+ if (!pkey ) goto bail ;
386+
387+ ctx -> ctx [side ] = EVP_PKEY_CTX_new (pkey , NULL );
388+ if (!ctx -> ctx [side ]) goto bail1 ;
389+
390+ if (!EVP_PKEY_get_bn_param (pkey , "qx" , & bn_x ) ||
391+ !EVP_PKEY_get_bn_param (pkey , "qy" , & bn_y )) {
392+ goto bail2 ;
393+ }
394+
395+ cbn [0 ] = bn_x ;
396+ if (!EVP_PKEY_get_bn_param (pkey , "priv" , (BIGNUM * * )& cbn [1 ])) {
397+ goto bail2 ;
398+ }
399+ cbn [2 ] = bn_y ;
400+
401+ el [LWS_GENCRYPTO_EC_KEYEL_CRV ].len = (uint32_t )strlen (curve_name ) + 1 ;
402+ el [LWS_GENCRYPTO_EC_KEYEL_CRV ].buf =
403+ lws_malloc (el [LWS_GENCRYPTO_EC_KEYEL_CRV ].len , "ec" );
404+ if (!el [LWS_GENCRYPTO_EC_KEYEL_CRV ].buf ) {
405+ lwsl_err ("%s: OOM\n" , __func__ );
406+ goto bail2 ;
407+ }
408+
409+ strcpy ((char * )el [LWS_GENCRYPTO_EC_KEYEL_CRV ].buf , curve_name );
410+
411+ for (n = LWS_GENCRYPTO_EC_KEYEL_X ; n < LWS_GENCRYPTO_EC_KEYEL_COUNT ;
412+ n ++ ) {
413+ el [n ].len = curve -> key_bytes ;
414+ el [n ].buf = lws_malloc (curve -> key_bytes , "ec" );
415+ if (!el [n ].buf )
416+ goto bail2 ;
417+
418+ m = BN_bn2binpad (cbn [n - 1 ], el [n ].buf , (int32_t )el [n ].len );
419+ if ((uint32_t )m != el [n ].len )
420+ goto bail2 ;
421+ }
422+
423+ ctx -> has_private = 1 ;
424+
425+ ret = 0 ;
426+
427+ bail2 :
428+ BN_clear_free (bn_x );
429+ BN_clear_free (bn_y );
430+ if (cbn [1 ]) BN_clear_free ((BIGNUM * )cbn [1 ]);
431+ bail1 :
432+ EVP_PKEY_free (pkey );
433+ bail :
434+ #else
362435 ec = EC_KEY_new_by_curve_name (curve -> tls_lib_nid );
363436 if (!ec ) {
364437 lwsl_err ("%s: unknown nid %d\n" , __func__ , curve -> tls_lib_nid );
@@ -447,6 +520,7 @@ lws_genec_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
447520 EVP_PKEY_free (pkey );
448521bail :
449522 EC_KEY_free (ec );
523+ #endif
450524
451525 return ret ;
452526}
@@ -528,7 +602,9 @@ lws_genecdsa_hash_sign_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
528602 size_t hs = lws_genhash_size (hash_type );
529603 const BIGNUM * r = NULL , * s = NULL ;
530604 ECDSA_SIG * ecdsasig ;
605+ #if !defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
531606 EC_KEY * eckey ;
607+ #endif
532608
533609 if (ctx -> genec_alg != LEGENEC_ECDSA ) {
534610 lwsl_notice ("%s: ctx alg %d\n" , __func__ , ctx -> genec_alg );
@@ -544,8 +620,6 @@ lws_genecdsa_hash_sign_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
544620 return -1 ;
545621 }
546622
547- eckey = EVP_PKEY_get1_EC_KEY (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]));
548-
549623 /*
550624 * The ECDSA P-256 SHA-256 digital signature is generated as follows:
551625 *
@@ -565,8 +639,39 @@ lws_genecdsa_hash_sign_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
565639 * 4. The resulting 64-octet sequence is the JWS Signature value.
566640 */
567641
642+ #if defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
643+ {
644+ EVP_PKEY_CTX * sctx ;
645+ unsigned char der_sig [256 ];
646+ size_t der_sig_len = sizeof (der_sig );
647+ const unsigned char * p = der_sig ;
648+
649+ sctx = EVP_PKEY_CTX_new (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]), NULL );
650+ if (!sctx ) {
651+ lwsl_notice ("%s: EVP_PKEY_CTX_new fail\n" , __func__ );
652+ goto bail ;
653+ }
654+
655+ if (EVP_PKEY_sign_init (sctx ) <= 0 ) {
656+ lwsl_notice ("%s: EVP_PKEY_sign_init fail\n" , __func__ );
657+ EVP_PKEY_CTX_free (sctx );
658+ goto bail ;
659+ }
660+
661+ if (EVP_PKEY_sign (sctx , der_sig , & der_sig_len , in , hs ) <= 0 ) {
662+ lwsl_notice ("%s: EVP_PKEY_sign fail\n" , __func__ );
663+ EVP_PKEY_CTX_free (sctx );
664+ goto bail ;
665+ }
666+ EVP_PKEY_CTX_free (sctx );
667+
668+ ecdsasig = d2i_ECDSA_SIG (NULL , & p , (long )der_sig_len );
669+ }
670+ #else
671+ eckey = EVP_PKEY_get1_EC_KEY (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]));
568672 ecdsasig = ECDSA_do_sign (in , SSL_SIZE_T_CAST (hs ), eckey );
569673 EC_KEY_free (eckey );
674+ #endif
570675 if (!ecdsasig ) {
571676 lwsl_notice ("%s: ECDSA_do_sign fail\n" , __func__ );
572677 goto bail ;
@@ -611,7 +716,9 @@ lws_genecdsa_hash_sig_verify_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
611716 keybytes = lws_gencrypto_bits_to_bytes (keybits );
612717 ECDSA_SIG * ecsig = ECDSA_SIG_new ();
613718 BIGNUM * r = NULL , * s = NULL ;
719+ #if !defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
614720 EC_KEY * eckey ;
721+ #endif
615722
616723 if (!ecsig )
617724 return -1 ;
@@ -655,10 +762,44 @@ lws_genecdsa_hash_sig_verify_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
655762 goto bail1 ;
656763 }
657764
658- eckey = EVP_PKEY_get1_EC_KEY (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]));
765+ #if defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
766+ {
767+ unsigned char * der = NULL ;
768+ int der_len ;
769+ EVP_PKEY_CTX * vctx ;
770+
771+ der_len = i2d_ECDSA_SIG (ecsig , & der );
772+ if (der_len <= 0 ) {
773+ n = -1 ;
774+ goto v_bail ;
775+ }
776+
777+ vctx = EVP_PKEY_CTX_new (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]), NULL );
778+ if (!vctx ) {
779+ OPENSSL_free (der );
780+ n = -1 ;
781+ goto v_bail ;
782+ }
659783
784+ if (EVP_PKEY_verify_init (vctx ) <= 0 ) {
785+ EVP_PKEY_CTX_free (vctx );
786+ OPENSSL_free (der );
787+ n = -1 ;
788+ goto v_bail ;
789+ }
790+
791+ n = EVP_PKEY_verify (vctx , der , (size_t )der_len , in , (size_t )hlen );
792+ EVP_PKEY_CTX_free (vctx );
793+ OPENSSL_free (der );
794+ v_bail :
795+ ;
796+ }
797+ #else
798+ eckey = EVP_PKEY_get1_EC_KEY (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [0 ]));
660799 n = ECDSA_do_verify (in , SSL_SIZE_T_CAST (hlen ), ecsig , eckey );
661800 EC_KEY_free (eckey );
801+ #endif
802+
662803 if (n != 1 ) {
663804 unsigned long err = ERR_get_error ();
664805 char buf [256 ];
@@ -687,15 +828,46 @@ int
687828lws_genecdh_compute_shared_secret (struct lws_genec_ctx * ctx , uint8_t * ss ,
688829 int * ss_len )
689830{
690- int len , ret = -1 ;
831+ int ret = -1 ;
832+ #if !defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
833+ int len ;
691834 EC_KEY * eckey [2 ];
835+ #endif
692836
693837 if (!ctx -> ctx [LDHS_OURS ] || !ctx -> ctx [LDHS_THEIRS ]) {
694838 lwsl_err ("%s: both sides must be set up\n" , __func__ );
695839
696840 return -1 ;
697841 }
698842
843+ #if defined(LWS_HAVE_EVP_PKEY_GET_BN_PARAM )
844+ {
845+ EVP_PKEY_CTX * dctx ;
846+ size_t slen = (size_t )* ss_len ;
847+
848+ dctx = EVP_PKEY_CTX_new (EVP_PKEY_CTX_get0_pkey (ctx -> ctx [LDHS_OURS ]), NULL );
849+ if (!dctx )
850+ return -1 ;
851+
852+ if (EVP_PKEY_derive_init (dctx ) <= 0 ) {
853+ EVP_PKEY_CTX_free (dctx );
854+ return -1 ;
855+ }
856+ if (EVP_PKEY_derive_set_peer (dctx , EVP_PKEY_CTX_get0_pkey (ctx -> ctx [LDHS_THEIRS ])) <= 0 ) {
857+ EVP_PKEY_CTX_free (dctx );
858+ return -1 ;
859+ }
860+
861+ if (EVP_PKEY_derive (dctx , ss , & slen ) <= 0 ) {
862+ EVP_PKEY_CTX_free (dctx );
863+ return -1 ;
864+ }
865+
866+ * ss_len = (int )slen ;
867+ ret = 0 ;
868+ EVP_PKEY_CTX_free (dctx );
869+ }
870+ #else
699871 eckey [LDHS_OURS ] = EVP_PKEY_get1_EC_KEY (
700872 EVP_PKEY_CTX_get0_pkey (ctx -> ctx [LDHS_OURS ]));
701873 eckey [LDHS_THEIRS ] = EVP_PKEY_get1_EC_KEY (
@@ -721,6 +893,7 @@ lws_genecdh_compute_shared_secret(struct lws_genec_ctx *ctx, uint8_t *ss,
721893
722894 EC_KEY_free (eckey [LDHS_OURS ]);
723895 EC_KEY_free (eckey [LDHS_THEIRS ]);
896+ #endif
724897
725898 return ret ;
726899}
0 commit comments