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