• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  *  lws_genec provides an EC abstraction api in lws that works the
25  *  same whether you are using openssl or mbedtls crypto functions underneath.
26  */
27 #include "private-lib-core.h"
28 #include "private-lib-tls-openssl.h"
29 
30 #if !defined(OPENSSL_NO_EC) && defined(LWS_HAVE_EC_KEY_new_by_curve_name) && \
31     (OPENSSL_VERSION_NUMBER >= 0x30000000l) && \
32      !defined(LWS_SUPPRESS_DEPRECATED_API_WARNINGS)
33 /* msvc doesn't have #warning... */
34 #error "You probably need LWS_SUPPRESS_DEPRECATED_API_WARNINGS"
35 #endif
36 
37 #if defined(USE_WOLFSSL)
38 #include "openssl/ecdh.h"
39 #endif
40 
41 /*
42  * Care: many openssl apis return 1 for success.  These are translated to the
43  * lws convention of 0 for success.
44  */
45 
46 #if defined(USE_WOLFSSL)
EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX * p)47 EVP_PKEY * EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *p)
48 {
49 	return p->pkey;
50 }
51 #endif
52 
53 #if !defined(LWS_HAVE_ECDSA_SIG_set0)
54 static void
ECDSA_SIG_get0(const ECDSA_SIG * sig,const BIGNUM ** pr,const BIGNUM ** ps)55 ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
56 {
57     if (pr != NULL)
58         *pr = sig->r;
59     if (ps != NULL)
60         *ps = sig->s;
61 }
62 
63 static int
ECDSA_SIG_set0(ECDSA_SIG * sig,BIGNUM * r,BIGNUM * s)64 ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
65 {
66 	if (r == NULL || s == NULL)
67 		return 0;
68 	BN_clear_free(sig->r);
69 	BN_clear_free(sig->s);
70 	sig->r = r;
71 	sig->s = s;
72 
73 	return 1;
74 }
75 #endif
76 #if !defined(LWS_HAVE_BN_bn2binpad)
BN_bn2binpad(const BIGNUM * a,unsigned char * to,int tolen)77 int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
78 {
79     int i;
80 #if !defined(USE_WOLFSSL)
81     BN_ULONG l;
82 #endif
83 
84 #if !defined(LIBRESSL_VERSION_NUMBER) && !defined(USE_WOLFSSL)
85     bn_check_top(a);
86 #endif
87     i = BN_num_bytes(a);
88 
89     /* Add leading zeroes if necessary */
90     if (tolen > i) {
91         memset(to, 0, (size_t)(tolen - i));
92         to += tolen - i;
93     }
94 #if defined(USE_WOLFSSL)
95     BN_bn2bin(a, to);
96 #else
97     while (i--) {
98         l = a->d[i / BN_BYTES];
99         *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
100     }
101 #endif
102     return tolen;
103 }
104 #endif
105 
106 const struct lws_ec_curves lws_ec_curves[4] = {
107 	/*
108 	 * These are the curves we are willing to use by default...
109 	 *
110 	 * The 3 recommended+ (P-256) and optional curves in RFC7518 7.6
111 	 *
112 	 * Specific keys lengths from RFC8422 p20
113 	 */
114 	{ "P-256", NID_X9_62_prime256v1, 32 },
115 	{ "P-384", NID_secp384r1,	 48 },
116 	{ "P-521", NID_secp521r1,	 66 },
117 
118 	{ NULL, 0, 0 }
119 };
120 
121 static int
lws_genec_eckey_import(int nid,EVP_PKEY * pkey,const struct lws_gencrypto_keyelem * el)122 lws_genec_eckey_import(int nid, EVP_PKEY *pkey,
123 		       const struct lws_gencrypto_keyelem *el)
124 {
125 	EC_KEY *ec = EC_KEY_new_by_curve_name(nid);
126 	BIGNUM *bn_d, *bn_x, *bn_y;
127 	int n;
128 
129 	if (!ec)
130 		return -1;
131 
132 	/*
133 	 * EC_KEY contains
134 	 *
135 	 * EC_GROUP * 	group
136 	 * EC_POINT * 	pub_key
137 	 * BIGNUM * 	priv_key  (ie, d)
138 	 */
139 
140 	bn_x = BN_bin2bn(el[LWS_GENCRYPTO_EC_KEYEL_X].buf,
141 			 (int)el[LWS_GENCRYPTO_EC_KEYEL_X].len, NULL);
142 	if (!bn_x) {
143 		lwsl_err("%s: BN_bin2bn (x) fail\n", __func__);
144 		goto bail;
145 	}
146 	bn_y = BN_bin2bn(el[LWS_GENCRYPTO_EC_KEYEL_Y].buf,
147 			(int)el[LWS_GENCRYPTO_EC_KEYEL_Y].len, NULL);
148 	if (!bn_y) {
149 		lwsl_err("%s: BN_bin2bn (y) fail\n", __func__);
150 		goto bail1;
151 	}
152 
153 	/*
154 	 * EC_KEY_set_public_key_affine_coordinates sets the public key for
155 	 * key based on its affine co-ordinates, i.e. it constructs an
156 	 * EC_POINT object based on the supplied x and y values and sets
157 	 * the public key to be this EC_POINT. It will also performs
158 	 * certain sanity checks on the key to confirm that it is valid.
159 	 */
160 
161 #if defined(USE_WOLFSSL)
162 	n = wolfSSL_EC_POINT_set_affine_coordinates_GFp(ec->group,
163                                                 ec->pub_key,
164                                                 bn_x, bn_y,
165                                                 NULL);
166 #else
167 	n = EC_KEY_set_public_key_affine_coordinates(ec, bn_x, bn_y);
168 #endif
169 	BN_free(bn_x);
170 	BN_free(bn_y);
171 	if (n != 1) {
172 		lwsl_err("%s: EC_KEY_set_public_key_affine_coordinates fail:\n",
173 			 __func__);
174 		lws_tls_err_describe_clear();
175 		goto bail;
176 	}
177 
178 	if (el[LWS_GENCRYPTO_EC_KEYEL_D].len) {
179 		bn_d = BN_bin2bn(el[LWS_GENCRYPTO_EC_KEYEL_D].buf,
180 				(int)el[LWS_GENCRYPTO_EC_KEYEL_D].len, NULL);
181 		if (!bn_d) {
182 			lwsl_err("%s: BN_bin2bn (d) fail\n", __func__);
183 			goto bail;
184 		}
185 
186 		n = EC_KEY_set_private_key(ec, bn_d);
187 		BN_clear_free(bn_d);
188 		if (n != 1) {
189 			lwsl_err("%s: EC_KEY_set_private_key fail\n", __func__);
190 			goto bail;
191 		}
192 	}
193 
194 	/* explicitly confirm the key pieces are consistent */
195 
196 #if !defined(USE_WOLFSSL)
197 	if (EC_KEY_check_key(ec) != 1) {
198 		lwsl_err("%s: EC_KEY_set_private_key fail\n", __func__);
199 		goto bail;
200 	}
201 #endif
202 
203 	n = EVP_PKEY_assign_EC_KEY(pkey, ec);
204 	if (n != 1) {
205 		lwsl_err("%s: EVP_PKEY_set1_EC_KEY failed\n", __func__);
206 		return -1;
207 	}
208 
209 	return 0;
210 
211 bail1:
212 	BN_free(bn_x);
213 bail:
214 	EC_KEY_free(ec);
215 
216 	return -1;
217 }
218 
219 static int
lws_genec_keypair_import(struct lws_genec_ctx * ctx,const struct lws_ec_curves * curve_table,EVP_PKEY_CTX ** pctx,const struct lws_gencrypto_keyelem * el)220 lws_genec_keypair_import(struct lws_genec_ctx *ctx,
221 			 const struct lws_ec_curves *curve_table,
222 			 EVP_PKEY_CTX **pctx,
223 			 const struct lws_gencrypto_keyelem *el)
224 {
225 	EVP_PKEY *pkey = NULL;
226 	const struct lws_ec_curves *curve;
227 
228 	if (el[LWS_GENCRYPTO_EC_KEYEL_CRV].len < 4)
229 		return -2;
230 
231 	curve = lws_genec_curve(curve_table,
232 				(char *)el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf);
233 	if (!curve)
234 		return -3;
235 
236 	if ((el[LWS_GENCRYPTO_EC_KEYEL_D].len &&
237 	     el[LWS_GENCRYPTO_EC_KEYEL_D].len != curve->key_bytes) ||
238 	    el[LWS_GENCRYPTO_EC_KEYEL_X].len != curve->key_bytes ||
239 	    el[LWS_GENCRYPTO_EC_KEYEL_Y].len != curve->key_bytes)
240 		return -4;
241 
242 	ctx->has_private = !!el[LWS_GENCRYPTO_EC_KEYEL_D].len;
243 
244 	pkey = EVP_PKEY_new();
245 	if (!pkey)
246 		return -7;
247 
248 	if (lws_genec_eckey_import(curve->tls_lib_nid, pkey, el)) {
249 		lwsl_err("%s: lws_genec_eckey_import fail\n", __func__);
250 		goto bail;
251 	}
252 
253 	*pctx = EVP_PKEY_CTX_new(pkey, NULL);
254 	EVP_PKEY_free(pkey);
255 	pkey = NULL;
256 
257 	if (!*pctx)
258 		goto bail;
259 
260 	return 0;
261 
262 bail:
263 	if (pkey)
264 		EVP_PKEY_free(pkey);
265 
266 	if (*pctx) {
267 		EVP_PKEY_CTX_free(*pctx);
268 		*pctx = NULL;
269 	}
270 
271 	return -9;
272 }
273 
274 int
lws_genecdh_create(struct lws_genec_ctx * ctx,struct lws_context * context,const struct lws_ec_curves * curve_table)275 lws_genecdh_create(struct lws_genec_ctx *ctx, struct lws_context *context,
276 		   const struct lws_ec_curves *curve_table)
277 {
278 	ctx->context = context;
279 	ctx->ctx[0] = NULL;
280 	ctx->ctx[1] = NULL;
281 	ctx->curve_table = curve_table;
282 	ctx->genec_alg = LEGENEC_ECDH;
283 
284 	return 0;
285 }
286 
287 int
lws_genecdsa_create(struct lws_genec_ctx * ctx,struct lws_context * context,const struct lws_ec_curves * curve_table)288 lws_genecdsa_create(struct lws_genec_ctx *ctx, struct lws_context *context,
289 		    const struct lws_ec_curves *curve_table)
290 {
291 	ctx->context = context;
292 	ctx->ctx[0] = NULL;
293 	ctx->ctx[1] = NULL;
294 	ctx->curve_table = curve_table;
295 	ctx->genec_alg = LEGENEC_ECDSA;
296 
297 	return 0;
298 }
299 
300 int
lws_genecdh_set_key(struct lws_genec_ctx * ctx,struct lws_gencrypto_keyelem * el,enum enum_lws_dh_side side)301 lws_genecdh_set_key(struct lws_genec_ctx *ctx, struct lws_gencrypto_keyelem *el,
302 		    enum enum_lws_dh_side side)
303 {
304 	if (ctx->genec_alg != LEGENEC_ECDH)
305 		return -1;
306 
307 	return lws_genec_keypair_import(ctx, ctx->curve_table, &ctx->ctx[side], el);
308 }
309 
310 int
lws_genecdsa_set_key(struct lws_genec_ctx * ctx,const struct lws_gencrypto_keyelem * el)311 lws_genecdsa_set_key(struct lws_genec_ctx *ctx,
312 		     const struct lws_gencrypto_keyelem *el)
313 {
314 	if (ctx->genec_alg != LEGENEC_ECDSA)
315 		return -1;
316 
317 	return lws_genec_keypair_import(ctx, ctx->curve_table, &ctx->ctx[0], el);
318 }
319 
320 static void
lws_genec_keypair_destroy(EVP_PKEY_CTX ** pctx)321 lws_genec_keypair_destroy(EVP_PKEY_CTX **pctx)
322 {
323 	if (!*pctx)
324 		return;
325 
326 //	lwsl_err("%p\n", EVP_PKEY_get1_EC_KEY(EVP_PKEY_CTX_get0_pkey(*pctx)));
327 
328 //	EC_KEY_free(EVP_PKEY_get1_EC_KEY(EVP_PKEY_CTX_get0_pkey(*pctx)));
329 
330 	EVP_PKEY_CTX_free(*pctx);
331 	*pctx = NULL;
332 }
333 
334 void
lws_genec_destroy(struct lws_genec_ctx * ctx)335 lws_genec_destroy(struct lws_genec_ctx *ctx)
336 {
337 	if (ctx->ctx[0])
338 		lws_genec_keypair_destroy(&ctx->ctx[0]);
339 	if (ctx->ctx[1])
340 		lws_genec_keypair_destroy(&ctx->ctx[1]);
341 }
342 
343 static int
lws_genec_new_keypair(struct lws_genec_ctx * ctx,enum enum_lws_dh_side side,const char * curve_name,struct lws_gencrypto_keyelem * el)344 lws_genec_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
345 		      const char *curve_name, struct lws_gencrypto_keyelem *el)
346 {
347 	const struct lws_ec_curves *curve;
348 	const EC_POINT *pubkey;
349 	EVP_PKEY *pkey = NULL;
350 	int ret = -29, n, m;
351 	BIGNUM *bn[3];
352 	EC_KEY *ec;
353 
354 	curve = lws_genec_curve(ctx->curve_table, curve_name);
355 	if (!curve) {
356 		lwsl_err("%s: curve '%s' not supported\n",
357 			 __func__, curve_name);
358 
359 		return -22;
360 	}
361 
362 	ec = EC_KEY_new_by_curve_name(curve->tls_lib_nid);
363 	if (!ec) {
364 		lwsl_err("%s: unknown nid %d\n", __func__, curve->tls_lib_nid);
365 		return -23;
366 	}
367 
368 	if (EC_KEY_generate_key(ec) != 1) {
369 		lwsl_err("%s: EC_KEY_generate_key failed\n", __func__);
370 		goto bail;
371 	}
372 
373 	pkey = EVP_PKEY_new();
374 	if (!pkey)
375 		goto bail;
376 
377 	if (EVP_PKEY_set1_EC_KEY(pkey, ec) != 1) {
378 		lwsl_err("%s: EVP_PKEY_assign_EC_KEY failed\n", __func__);
379 		goto bail1;
380 	}
381 
382 	ctx->ctx[side] = EVP_PKEY_CTX_new(pkey, NULL);
383 	if (!ctx->ctx[side]) {
384 		lwsl_err("%s: EVP_PKEY_CTX_new failed\n", __func__);
385 		goto bail1;
386 	}
387 
388 	/*
389 	 * we need to capture the individual element BIGNUMs into
390 	 * lws_gencrypto_keyelem, so they can be serialized, used in jwk etc
391 	 */
392 
393 	pubkey = EC_KEY_get0_public_key(ec);
394 	if (!pubkey) {
395 		lwsl_err("%s: EC_KEY_get0_public_key failed\n", __func__);
396 		goto bail1;
397 	}
398 
399 	bn[0] = BN_new();
400 	bn[1] = (BIGNUM *)EC_KEY_get0_private_key(ec);
401 	bn[2] = BN_new();
402 
403 #if defined(LWS_HAVE_EC_POINT_get_affine_coordinates)
404 	if (EC_POINT_get_affine_coordinates(EC_KEY_get0_group(ec),
405 #else
406 	if (EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
407 #endif
408 		        pubkey, bn[0], bn[2], NULL) != 1) {
409 		lwsl_err("%s: EC_POINT_get_affine_coordinates_GFp failed\n",
410 			 __func__);
411 		goto bail2;
412 	}
413 
414 	el[LWS_GENCRYPTO_EC_KEYEL_CRV].len = (uint32_t)strlen(curve_name) + 1;
415 	el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf =
416 			lws_malloc(el[LWS_GENCRYPTO_EC_KEYEL_CRV].len, "ec");
417 	if (!el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf) {
418 		lwsl_err("%s: OOM\n", __func__);
419 		goto bail2;
420 	}
421 
422 	strcpy((char *)el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf, curve_name);
423 
424 	for (n = LWS_GENCRYPTO_EC_KEYEL_X; n < LWS_GENCRYPTO_EC_KEYEL_COUNT;
425 	     n++) {
426 		el[n].len = curve->key_bytes;
427 		el[n].buf = lws_malloc(curve->key_bytes, "ec");
428 		if (!el[n].buf)
429 			goto bail2;
430 
431 		m = BN_bn2binpad(bn[n - 1], el[n].buf, (int32_t)el[n].len);
432 		if ((uint32_t)m != el[n].len)
433 			goto bail2;
434 	}
435 
436 	ctx->has_private = 1;
437 
438 	ret = 0;
439 
440 bail2:
441 	BN_clear_free(bn[0]);
442 	BN_clear_free(bn[2]);
443 bail1:
444 	EVP_PKEY_free(pkey);
445 bail:
446 	EC_KEY_free(ec);
447 
448 	return ret;
449 }
450 
451 int
lws_genecdh_new_keypair(struct lws_genec_ctx * ctx,enum enum_lws_dh_side side,const char * curve_name,struct lws_gencrypto_keyelem * el)452 lws_genecdh_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
453 			const char *curve_name,
454 			struct lws_gencrypto_keyelem *el)
455 {
456 	if (ctx->genec_alg != LEGENEC_ECDH)
457 		return -1;
458 
459 	return lws_genec_new_keypair(ctx, side, curve_name, el);
460 }
461 
462 int
lws_genecdsa_new_keypair(struct lws_genec_ctx * ctx,const char * curve_name,struct lws_gencrypto_keyelem * el)463 lws_genecdsa_new_keypair(struct lws_genec_ctx *ctx, const char *curve_name,
464 			 struct lws_gencrypto_keyelem *el)
465 {
466 	if (ctx->genec_alg != LEGENEC_ECDSA)
467 		return -1;
468 
469 	return lws_genec_new_keypair(ctx, LDHS_OURS, curve_name, el);
470 }
471 
472 #if 0
473 int
474 lws_genecdsa_hash_sign(struct lws_genec_ctx *ctx, const uint8_t *in,
475 		       enum lws_genhash_types hash_type,
476 		       uint8_t *sig, size_t sig_len)
477 {
478 	const EVP_MD *md = lws_gencrypto_openssl_hash_to_EVP_MD(hash_type);
479 	EVP_MD_CTX *mdctx = NULL;
480 
481 	if (ctx->genec_alg != LEGENEC_ECDSA)
482 		return -1;
483 
484 	if (!md)
485 		return -1;
486 
487 	mdctx = EVP_MD_CTX_create();
488 	if (!mdctx)
489 		goto bail;
490 
491 	if (EVP_DigestSignInit(mdctx, NULL, md, NULL,
492 			       EVP_PKEY_CTX_get0_pkey(ctx->ctx))) {
493 		lwsl_err("%s: EVP_DigestSignInit failed\n", __func__);
494 
495 		goto bail;
496 	}
497 	if (EVP_DigestSignUpdate(mdctx, in, EVP_MD_size(md))) {
498 		lwsl_err("%s: EVP_DigestSignUpdate failed\n", __func__);
499 
500 		goto bail;
501 	}
502 	if (EVP_DigestSignFinal(mdctx, sig, &sig_len)) {
503 		lwsl_err("%s: EVP_DigestSignFinal failed\n", __func__);
504 
505 		goto bail;
506 	}
507 
508 	EVP_MD_CTX_free(mdctx);
509 
510 	return (int)sig_len;
511 bail:
512 	if (mdctx)
513 		EVP_MD_CTX_free(mdctx);
514 
515 	return -1;
516 }
517 #endif
518 
519 int
lws_genecdsa_hash_sign_jws(struct lws_genec_ctx * ctx,const uint8_t * in,enum lws_genhash_types hash_type,int keybits,uint8_t * sig,size_t sig_len)520 lws_genecdsa_hash_sign_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
521 			   enum lws_genhash_types hash_type, int keybits,
522 			   uint8_t *sig, size_t sig_len)
523 {
524 	int ret = -1, n, keybytes = lws_gencrypto_bits_to_bytes(keybits);
525 	size_t hs = lws_genhash_size(hash_type);
526 	const BIGNUM *r = NULL, *s = NULL;
527 	ECDSA_SIG *ecdsasig;
528 	EC_KEY *eckey;
529 
530 	if (ctx->genec_alg != LEGENEC_ECDSA) {
531 		lwsl_notice("%s: ctx alg %d\n", __func__, ctx->genec_alg);
532 		return -1;
533 	}
534 
535 	if (!ctx->has_private)
536 		return -1;
537 
538 	if ((int)sig_len != (int)(keybytes * 2)) {
539 		lwsl_notice("%s: sig buff %d < %d\n", __func__,
540 			    (int)sig_len, (int)(hs * 2));
541 		return -1;
542 	}
543 
544 	eckey = EVP_PKEY_get1_EC_KEY(EVP_PKEY_CTX_get0_pkey(ctx->ctx[0]));
545 
546 	/*
547 	 * The ECDSA P-256 SHA-256 digital signature is generated as follows:
548 	 *
549 	 * 1.  Generate a digital signature of the JWS Signing Input using ECDSA
550 	 *     P-256 SHA-256 with the desired private key.  The output will be
551 	 *     the pair (R, S), where R and S are 256-bit unsigned integers.
552 	 *
553 	 * 2.  Turn R and S into octet sequences in big-endian order, with each
554 	 *     array being be 32 octets long.  The octet sequence
555 	 *     representations MUST NOT be shortened to omit any leading zero
556 	 *     octets contained in the values.
557 	 *
558 	 * 3.  Concatenate the two octet sequences in the order R and then S.
559 	 *     (Note that many ECDSA implementations will directly produce this
560 	 *     concatenation as their output.)
561 	 *
562 	 * 4.  The resulting 64-octet sequence is the JWS Signature value.
563 	 */
564 
565 	ecdsasig = ECDSA_do_sign(in, (int)hs, eckey);
566 	EC_KEY_free(eckey);
567 	if (!ecdsasig) {
568 		lwsl_notice("%s: ECDSA_do_sign fail\n", __func__);
569 		goto bail;
570 	}
571 
572 	ECDSA_SIG_get0(ecdsasig, &r, &s);
573 
574 	/*
575 	 * in the 521-bit case, we have to pad the last byte as it only
576 	 * generates 65 bytes
577 	 */
578 
579 	n = BN_bn2binpad(r, sig, keybytes);
580 	if (n != keybytes) {
581 		lwsl_notice("%s: bignum r fail %d %d\n", __func__, n, keybytes);
582 		goto bail;
583 	}
584 
585 	n = BN_bn2binpad(s, sig + keybytes, keybytes);
586 	if (n != keybytes) {
587 		lwsl_notice("%s: bignum s fail %d %d\n", __func__, n, keybytes);
588 		goto bail;
589 	}
590 
591 	ret = 0;
592 
593 bail:
594 	if (ecdsasig)
595 		ECDSA_SIG_free(ecdsasig);
596 
597 	return ret;
598 }
599 
600 /* in is the JWS Signing Input hash */
601 
602 int
lws_genecdsa_hash_sig_verify_jws(struct lws_genec_ctx * ctx,const uint8_t * in,enum lws_genhash_types hash_type,int keybits,const uint8_t * sig,size_t sig_len)603 lws_genecdsa_hash_sig_verify_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
604 				 enum lws_genhash_types hash_type, int keybits,
605 				 const uint8_t *sig, size_t sig_len)
606 {
607 	int ret = -1, n, hlen = (int)lws_genhash_size(hash_type),
608 			keybytes = lws_gencrypto_bits_to_bytes(keybits);
609 	ECDSA_SIG *ecsig = ECDSA_SIG_new();
610 	BIGNUM *r = NULL, *s = NULL;
611 	EC_KEY *eckey;
612 
613 	if (!ecsig)
614 		return -1;
615 
616 	if (ctx->genec_alg != LEGENEC_ECDSA)
617 		goto bail;
618 
619 	if ((int)sig_len != keybytes * 2) {
620 		lwsl_err("%s: sig buf size %d vs %d\n", __func__,
621 			 (int)sig_len, keybytes * 2);
622 		goto bail;
623 	}
624 	/*
625 	 * 1.  The JWS Signature value MUST be a 64-octet sequence.  If it is
626 	 *     not a 64-octet sequence, the validation has failed.
627 	 *
628 	 * 2.  Split the 64-octet sequence into two 32-octet sequences.  The
629 	 *     first octet sequence represents R and the second S.  The values R
630 	 *     and S are represented as octet sequences using the Integer-to-
631 	 *     OctetString Conversion defined in Section 2.3.7 of SEC1 [SEC1]
632 	 *     (in big-endian octet order).
633 	 *
634 	 * 3.  Submit the JWS Signing Input, R, S, and the public key (x, y) to
635 	 *     the ECDSA P-256 SHA-256 validator.
636 	 */
637 
638 	r = BN_bin2bn(sig, keybytes, NULL);
639 	if (!r) {
640 		lwsl_err("%s: BN_bin2bn (r) fail\n", __func__);
641 		goto bail;
642 	}
643 
644 	s = BN_bin2bn(sig + keybytes, keybytes, NULL);
645 	if (!s) {
646 		lwsl_err("%s: BN_bin2bn (s) fail\n", __func__);
647 		goto bail1;
648 	}
649 
650 	if (ECDSA_SIG_set0(ecsig, r, s) != 1) {
651 		lwsl_err("%s: ECDSA_SIG_set0 fail\n", __func__);
652 		goto bail1;
653 	}
654 
655 	eckey = EVP_PKEY_get1_EC_KEY(EVP_PKEY_CTX_get0_pkey(ctx->ctx[0]));
656 
657 	n = ECDSA_do_verify(in, hlen, ecsig, eckey);
658 	EC_KEY_free(eckey);
659 	if (n != 1) {
660 		lwsl_err("%s: ECDSA_do_verify fail, hlen %d\n", __func__, (int)hlen);
661 		lws_tls_err_describe_clear();
662 		goto bail;
663 	}
664 
665 	ret = 0;
666 	goto bail;
667 
668 bail1:
669 	if (r)
670 		BN_free(r);
671 	if (s)
672 		BN_free(s);
673 
674 bail:
675 	ECDSA_SIG_free(ecsig);
676 
677 	return ret;
678 }
679 
680 int
lws_genecdh_compute_shared_secret(struct lws_genec_ctx * ctx,uint8_t * ss,int * ss_len)681 lws_genecdh_compute_shared_secret(struct lws_genec_ctx *ctx, uint8_t *ss,
682 				  int *ss_len)
683 {
684 	int len, ret = -1;
685 	EC_KEY *eckey[2];
686 
687 	if (!ctx->ctx[LDHS_OURS] || !ctx->ctx[LDHS_THEIRS]) {
688 		lwsl_err("%s: both sides must be set up\n", __func__);
689 
690 		return -1;
691 	}
692 
693 	eckey[LDHS_OURS] = EVP_PKEY_get1_EC_KEY(
694 				EVP_PKEY_CTX_get0_pkey(ctx->ctx[LDHS_OURS]));
695 	eckey[LDHS_THEIRS] = EVP_PKEY_get1_EC_KEY(
696 				EVP_PKEY_CTX_get0_pkey(ctx->ctx[LDHS_THEIRS]));
697 
698 	len = (EC_GROUP_get_degree(EC_KEY_get0_group(eckey[LDHS_OURS])) + 7) / 8;
699 	if (len <= *ss_len) {
700 #if defined(USE_WOLFSSL)
701 		*ss_len = wolfSSL_ECDH_compute_key(
702 #else
703 		*ss_len = ECDH_compute_key(
704 #endif
705 				ss, (unsigned int)len,
706 				EC_KEY_get0_public_key(eckey[LDHS_THEIRS]),
707 				eckey[LDHS_OURS], NULL);
708 		ret = -(*ss_len < 0);
709 	}
710 
711 	EC_KEY_free(eckey[LDHS_OURS]);
712 	EC_KEY_free(eckey[LDHS_THEIRS]);
713 
714 	return ret;
715 }
716