xref: /aosp_15_r20/external/libwebsockets/lib/tls/mbedtls/lws-genec.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker  /*
2*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  *
24*1c60b9acSAndroid Build Coastguard Worker  *  lws_genec provides an EC abstraction api in lws that works the
25*1c60b9acSAndroid Build Coastguard Worker  *  same whether you are using openssl or mbedtls crypto functions underneath.
26*1c60b9acSAndroid Build Coastguard Worker  */
27*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
28*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-tls-mbedtls.h"
29*1c60b9acSAndroid Build Coastguard Worker 
30*1c60b9acSAndroid Build Coastguard Worker #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
31*1c60b9acSAndroid Build Coastguard Worker #define ECDHCTX(_c, _ins) _c->u.ctx_ecdh->MBEDTLS_PRIVATE(ctx).\
32*1c60b9acSAndroid Build Coastguard Worker 			MBEDTLS_PRIVATE(mbed_ecdh).MBEDTLS_PRIVATE(_ins)
33*1c60b9acSAndroid Build Coastguard Worker #define ECDSACTX(_c, _ins) _c->u.ctx_ecdsa->MBEDTLS_PRIVATE(_ins)
34*1c60b9acSAndroid Build Coastguard Worker #else
35*1c60b9acSAndroid Build Coastguard Worker #define ECDHCTX(_c, _ins) _c->u.ctx_ecdh->_ins
36*1c60b9acSAndroid Build Coastguard Worker #define ECDSACTX(_c, _ins) _c->u.ctx_ecdsa->_ins
37*1c60b9acSAndroid Build Coastguard Worker #endif
38*1c60b9acSAndroid Build Coastguard Worker 
39*1c60b9acSAndroid Build Coastguard Worker const struct lws_ec_curves lws_ec_curves[] = {
40*1c60b9acSAndroid Build Coastguard Worker 	/*
41*1c60b9acSAndroid Build Coastguard Worker 	 * These are the curves we are willing to use by default...
42*1c60b9acSAndroid Build Coastguard Worker 	 *
43*1c60b9acSAndroid Build Coastguard Worker 	 * The 3 recommended+ (P-256) and optional curves in RFC7518 7.6
44*1c60b9acSAndroid Build Coastguard Worker 	 *
45*1c60b9acSAndroid Build Coastguard Worker 	 * Specific keys lengths from RFC8422 p20
46*1c60b9acSAndroid Build Coastguard Worker 	 */
47*1c60b9acSAndroid Build Coastguard Worker 	{ "P-256", MBEDTLS_ECP_DP_SECP256R1, 32 },
48*1c60b9acSAndroid Build Coastguard Worker 	{ "P-384", MBEDTLS_ECP_DP_SECP384R1, 48 },
49*1c60b9acSAndroid Build Coastguard Worker 	{ "P-521", MBEDTLS_ECP_DP_SECP521R1, 66 },
50*1c60b9acSAndroid Build Coastguard Worker 
51*1c60b9acSAndroid Build Coastguard Worker 	{ NULL, 0, 0 }
52*1c60b9acSAndroid Build Coastguard Worker };
53*1c60b9acSAndroid Build Coastguard Worker 
54*1c60b9acSAndroid Build Coastguard Worker static int
lws_genec_keypair_import(struct lws_genec_ctx * ctx,enum enum_lws_dh_side side,const struct lws_gencrypto_keyelem * el)55*1c60b9acSAndroid Build Coastguard Worker lws_genec_keypair_import(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
56*1c60b9acSAndroid Build Coastguard Worker 			 const struct lws_gencrypto_keyelem *el)
57*1c60b9acSAndroid Build Coastguard Worker {
58*1c60b9acSAndroid Build Coastguard Worker 	const struct lws_ec_curves *curve;
59*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecp_keypair kp;
60*1c60b9acSAndroid Build Coastguard Worker 	int ret = -1;
61*1c60b9acSAndroid Build Coastguard Worker 
62*1c60b9acSAndroid Build Coastguard Worker 	if (el[LWS_GENCRYPTO_EC_KEYEL_CRV].len < 4) {
63*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: crv '%s' (%d)\n", __func__,
64*1c60b9acSAndroid Build Coastguard Worker 			    el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf ?
65*1c60b9acSAndroid Build Coastguard Worker 				    (char *)el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf :
66*1c60b9acSAndroid Build Coastguard Worker 					    "null",
67*1c60b9acSAndroid Build Coastguard Worker 			    el[LWS_GENCRYPTO_EC_KEYEL_CRV].len);
68*1c60b9acSAndroid Build Coastguard Worker 		return -21;
69*1c60b9acSAndroid Build Coastguard Worker 	}
70*1c60b9acSAndroid Build Coastguard Worker 
71*1c60b9acSAndroid Build Coastguard Worker 	curve = lws_genec_curve(ctx->curve_table,
72*1c60b9acSAndroid Build Coastguard Worker 				(char *)el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf);
73*1c60b9acSAndroid Build Coastguard Worker 	if (!curve)
74*1c60b9acSAndroid Build Coastguard Worker 		return -22;
75*1c60b9acSAndroid Build Coastguard Worker 
76*1c60b9acSAndroid Build Coastguard Worker 	/*
77*1c60b9acSAndroid Build Coastguard Worker 	 * d (the private part) may be missing, otherwise it and everything
78*1c60b9acSAndroid Build Coastguard Worker 	 * else must match the expected bignum size
79*1c60b9acSAndroid Build Coastguard Worker 	 */
80*1c60b9acSAndroid Build Coastguard Worker 
81*1c60b9acSAndroid Build Coastguard Worker 	if ((el[LWS_GENCRYPTO_EC_KEYEL_D].len &&
82*1c60b9acSAndroid Build Coastguard Worker 	     el[LWS_GENCRYPTO_EC_KEYEL_D].len != curve->key_bytes) ||
83*1c60b9acSAndroid Build Coastguard Worker 	    el[LWS_GENCRYPTO_EC_KEYEL_X].len != curve->key_bytes ||
84*1c60b9acSAndroid Build Coastguard Worker 	    el[LWS_GENCRYPTO_EC_KEYEL_Y].len != curve->key_bytes)
85*1c60b9acSAndroid Build Coastguard Worker 		return -23;
86*1c60b9acSAndroid Build Coastguard Worker 
87*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecp_keypair_init(&kp);
88*1c60b9acSAndroid Build Coastguard Worker 	if (mbedtls_ecp_group_load(&kp.MBEDTLS_PRIVATE(grp),
89*1c60b9acSAndroid Build Coastguard Worker 				   (mbedtls_ecp_group_id)curve->tls_lib_nid))
90*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
91*1c60b9acSAndroid Build Coastguard Worker 
92*1c60b9acSAndroid Build Coastguard Worker 	ctx->has_private = !!el[LWS_GENCRYPTO_EC_KEYEL_D].len;
93*1c60b9acSAndroid Build Coastguard Worker 
94*1c60b9acSAndroid Build Coastguard Worker 	/* d (the private key) is directly an mpi */
95*1c60b9acSAndroid Build Coastguard Worker 
96*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->has_private &&
97*1c60b9acSAndroid Build Coastguard Worker 	    mbedtls_mpi_read_binary(&kp.MBEDTLS_PRIVATE(d),
98*1c60b9acSAndroid Build Coastguard Worker 				    el[LWS_GENCRYPTO_EC_KEYEL_D].buf,
99*1c60b9acSAndroid Build Coastguard Worker 				    el[LWS_GENCRYPTO_EC_KEYEL_D].len))
100*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
101*1c60b9acSAndroid Build Coastguard Worker 
102*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecp_set_zero(&kp.MBEDTLS_PRIVATE(Q));
103*1c60b9acSAndroid Build Coastguard Worker 
104*1c60b9acSAndroid Build Coastguard Worker 	if (mbedtls_mpi_read_binary(&kp.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X),
105*1c60b9acSAndroid Build Coastguard Worker 				    el[LWS_GENCRYPTO_EC_KEYEL_X].buf,
106*1c60b9acSAndroid Build Coastguard Worker 				    el[LWS_GENCRYPTO_EC_KEYEL_X].len))
107*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
108*1c60b9acSAndroid Build Coastguard Worker 
109*1c60b9acSAndroid Build Coastguard Worker 	if (mbedtls_mpi_read_binary(&kp.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y),
110*1c60b9acSAndroid Build Coastguard Worker 				    el[LWS_GENCRYPTO_EC_KEYEL_Y].buf,
111*1c60b9acSAndroid Build Coastguard Worker 				    el[LWS_GENCRYPTO_EC_KEYEL_Y].len))
112*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
113*1c60b9acSAndroid Build Coastguard Worker 
114*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_lset(&kp.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1);
115*1c60b9acSAndroid Build Coastguard Worker 
116*1c60b9acSAndroid Build Coastguard Worker 	switch (ctx->genec_alg) {
117*1c60b9acSAndroid Build Coastguard Worker 	case LEGENEC_ECDH:
118*1c60b9acSAndroid Build Coastguard Worker 		if (mbedtls_ecdh_get_params(ctx->u.ctx_ecdh, &kp,
119*1c60b9acSAndroid Build Coastguard Worker 					    (mbedtls_ecdh_side)side))
120*1c60b9acSAndroid Build Coastguard Worker 			goto bail1;
121*1c60b9acSAndroid Build Coastguard Worker 		/* verify the key is consistent with the claimed curve */
122*1c60b9acSAndroid Build Coastguard Worker 		if (ctx->has_private &&
123*1c60b9acSAndroid Build Coastguard Worker 		    mbedtls_ecp_check_privkey(&ECDHCTX(ctx, grp),
124*1c60b9acSAndroid Build Coastguard Worker 					      &ECDHCTX(ctx, d)))
125*1c60b9acSAndroid Build Coastguard Worker 			goto bail1;
126*1c60b9acSAndroid Build Coastguard Worker 		if (mbedtls_ecp_check_pubkey(&ECDHCTX(ctx, grp),
127*1c60b9acSAndroid Build Coastguard Worker 					     &ECDHCTX(ctx, Q)))
128*1c60b9acSAndroid Build Coastguard Worker 			goto bail1;
129*1c60b9acSAndroid Build Coastguard Worker 		break;
130*1c60b9acSAndroid Build Coastguard Worker 	case LEGENEC_ECDSA:
131*1c60b9acSAndroid Build Coastguard Worker 		if (mbedtls_ecdsa_from_keypair(ctx->u.ctx_ecdsa, &kp))
132*1c60b9acSAndroid Build Coastguard Worker 			goto bail1;
133*1c60b9acSAndroid Build Coastguard Worker 		/* verify the key is consistent with the claimed curve */
134*1c60b9acSAndroid Build Coastguard Worker 		if (ctx->has_private &&
135*1c60b9acSAndroid Build Coastguard Worker 		    mbedtls_ecp_check_privkey(&ECDSACTX(ctx, grp),
136*1c60b9acSAndroid Build Coastguard Worker 					      &ECDSACTX(ctx, d)))
137*1c60b9acSAndroid Build Coastguard Worker 			goto bail1;
138*1c60b9acSAndroid Build Coastguard Worker 		if (mbedtls_ecp_check_pubkey(&ECDSACTX(ctx, grp),
139*1c60b9acSAndroid Build Coastguard Worker 					     &ECDSACTX(ctx, Q)))
140*1c60b9acSAndroid Build Coastguard Worker 			goto bail1;
141*1c60b9acSAndroid Build Coastguard Worker 		break;
142*1c60b9acSAndroid Build Coastguard Worker 	default:
143*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
144*1c60b9acSAndroid Build Coastguard Worker 	}
145*1c60b9acSAndroid Build Coastguard Worker 
146*1c60b9acSAndroid Build Coastguard Worker 	ret = 0;
147*1c60b9acSAndroid Build Coastguard Worker 
148*1c60b9acSAndroid Build Coastguard Worker bail1:
149*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecp_keypair_free(&kp);
150*1c60b9acSAndroid Build Coastguard Worker 
151*1c60b9acSAndroid Build Coastguard Worker 	return ret;
152*1c60b9acSAndroid Build Coastguard Worker }
153*1c60b9acSAndroid Build Coastguard Worker 
154*1c60b9acSAndroid Build Coastguard Worker int
lws_genecdh_create(struct lws_genec_ctx * ctx,struct lws_context * context,const struct lws_ec_curves * curve_table)155*1c60b9acSAndroid Build Coastguard Worker lws_genecdh_create(struct lws_genec_ctx *ctx, struct lws_context *context,
156*1c60b9acSAndroid Build Coastguard Worker 		   const struct lws_ec_curves *curve_table)
157*1c60b9acSAndroid Build Coastguard Worker {
158*1c60b9acSAndroid Build Coastguard Worker 	memset(ctx, 0, sizeof(*ctx));
159*1c60b9acSAndroid Build Coastguard Worker 
160*1c60b9acSAndroid Build Coastguard Worker 	ctx->context = context;
161*1c60b9acSAndroid Build Coastguard Worker 	ctx->curve_table = curve_table;
162*1c60b9acSAndroid Build Coastguard Worker 	ctx->genec_alg = LEGENEC_ECDH;
163*1c60b9acSAndroid Build Coastguard Worker 
164*1c60b9acSAndroid Build Coastguard Worker 	ctx->u.ctx_ecdh = lws_zalloc(sizeof(*ctx->u.ctx_ecdh), "genecdh");
165*1c60b9acSAndroid Build Coastguard Worker 	if (!ctx->u.ctx_ecdh)
166*1c60b9acSAndroid Build Coastguard Worker 		return 1;
167*1c60b9acSAndroid Build Coastguard Worker 
168*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecdh_init(ctx->u.ctx_ecdh);
169*1c60b9acSAndroid Build Coastguard Worker 
170*1c60b9acSAndroid Build Coastguard Worker 	return 0;
171*1c60b9acSAndroid Build Coastguard Worker }
172*1c60b9acSAndroid Build Coastguard Worker 
173*1c60b9acSAndroid Build Coastguard Worker int
lws_genecdsa_create(struct lws_genec_ctx * ctx,struct lws_context * context,const struct lws_ec_curves * curve_table)174*1c60b9acSAndroid Build Coastguard Worker lws_genecdsa_create(struct lws_genec_ctx *ctx, struct lws_context *context,
175*1c60b9acSAndroid Build Coastguard Worker 		    const struct lws_ec_curves *curve_table)
176*1c60b9acSAndroid Build Coastguard Worker {
177*1c60b9acSAndroid Build Coastguard Worker 	memset(ctx, 0, sizeof(*ctx));
178*1c60b9acSAndroid Build Coastguard Worker 
179*1c60b9acSAndroid Build Coastguard Worker 	ctx->context = context;
180*1c60b9acSAndroid Build Coastguard Worker 	ctx->curve_table = curve_table;
181*1c60b9acSAndroid Build Coastguard Worker 	ctx->genec_alg = LEGENEC_ECDSA;
182*1c60b9acSAndroid Build Coastguard Worker 
183*1c60b9acSAndroid Build Coastguard Worker 	ctx->u.ctx_ecdsa = lws_zalloc(sizeof(*ctx->u.ctx_ecdsa), "genecdsa");
184*1c60b9acSAndroid Build Coastguard Worker 	if (!ctx->u.ctx_ecdsa)
185*1c60b9acSAndroid Build Coastguard Worker 		return 1;
186*1c60b9acSAndroid Build Coastguard Worker 
187*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecdsa_init(ctx->u.ctx_ecdsa);
188*1c60b9acSAndroid Build Coastguard Worker 
189*1c60b9acSAndroid Build Coastguard Worker 	return 0;
190*1c60b9acSAndroid Build Coastguard Worker }
191*1c60b9acSAndroid Build Coastguard Worker 
192*1c60b9acSAndroid Build Coastguard Worker 
193*1c60b9acSAndroid Build Coastguard Worker int
lws_genecdh_set_key(struct lws_genec_ctx * ctx,struct lws_gencrypto_keyelem * el,enum enum_lws_dh_side side)194*1c60b9acSAndroid Build Coastguard Worker lws_genecdh_set_key(struct lws_genec_ctx *ctx, struct lws_gencrypto_keyelem *el,
195*1c60b9acSAndroid Build Coastguard Worker 		    enum enum_lws_dh_side side)
196*1c60b9acSAndroid Build Coastguard Worker {
197*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->genec_alg != LEGENEC_ECDH)
198*1c60b9acSAndroid Build Coastguard Worker 		return -1;
199*1c60b9acSAndroid Build Coastguard Worker 
200*1c60b9acSAndroid Build Coastguard Worker 	return lws_genec_keypair_import(ctx, side, el);
201*1c60b9acSAndroid Build Coastguard Worker }
202*1c60b9acSAndroid Build Coastguard Worker 
203*1c60b9acSAndroid Build Coastguard Worker int
lws_genecdsa_set_key(struct lws_genec_ctx * ctx,const struct lws_gencrypto_keyelem * el)204*1c60b9acSAndroid Build Coastguard Worker lws_genecdsa_set_key(struct lws_genec_ctx *ctx,
205*1c60b9acSAndroid Build Coastguard Worker 		     const struct lws_gencrypto_keyelem *el)
206*1c60b9acSAndroid Build Coastguard Worker {
207*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->genec_alg != LEGENEC_ECDSA)
208*1c60b9acSAndroid Build Coastguard Worker 		return -1;
209*1c60b9acSAndroid Build Coastguard Worker 
210*1c60b9acSAndroid Build Coastguard Worker 	return lws_genec_keypair_import(ctx, 0, el);
211*1c60b9acSAndroid Build Coastguard Worker }
212*1c60b9acSAndroid Build Coastguard Worker 
213*1c60b9acSAndroid Build Coastguard Worker void
lws_genec_destroy(struct lws_genec_ctx * ctx)214*1c60b9acSAndroid Build Coastguard Worker lws_genec_destroy(struct lws_genec_ctx *ctx)
215*1c60b9acSAndroid Build Coastguard Worker {
216*1c60b9acSAndroid Build Coastguard Worker 	switch (ctx->genec_alg) {
217*1c60b9acSAndroid Build Coastguard Worker 	case LEGENEC_ECDH:
218*1c60b9acSAndroid Build Coastguard Worker 		if (ctx->u.ctx_ecdh) {
219*1c60b9acSAndroid Build Coastguard Worker 			mbedtls_ecdh_free(ctx->u.ctx_ecdh);
220*1c60b9acSAndroid Build Coastguard Worker 			lws_free(ctx->u.ctx_ecdh);
221*1c60b9acSAndroid Build Coastguard Worker 			ctx->u.ctx_ecdh = NULL;
222*1c60b9acSAndroid Build Coastguard Worker 		}
223*1c60b9acSAndroid Build Coastguard Worker 		break;
224*1c60b9acSAndroid Build Coastguard Worker 	case LEGENEC_ECDSA:
225*1c60b9acSAndroid Build Coastguard Worker 		if (ctx->u.ctx_ecdsa) {
226*1c60b9acSAndroid Build Coastguard Worker 			mbedtls_ecdsa_free(ctx->u.ctx_ecdsa);
227*1c60b9acSAndroid Build Coastguard Worker 			lws_free(ctx->u.ctx_ecdsa);
228*1c60b9acSAndroid Build Coastguard Worker 			ctx->u.ctx_ecdsa = NULL;
229*1c60b9acSAndroid Build Coastguard Worker 		}
230*1c60b9acSAndroid Build Coastguard Worker 		break;
231*1c60b9acSAndroid Build Coastguard Worker 	default:
232*1c60b9acSAndroid Build Coastguard Worker 		break;
233*1c60b9acSAndroid Build Coastguard Worker 	}
234*1c60b9acSAndroid Build Coastguard Worker }
235*1c60b9acSAndroid Build Coastguard Worker 
236*1c60b9acSAndroid Build Coastguard Worker 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)237*1c60b9acSAndroid Build Coastguard Worker lws_genecdh_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
238*1c60b9acSAndroid Build Coastguard Worker 			const char *curve_name,
239*1c60b9acSAndroid Build Coastguard Worker 			struct lws_gencrypto_keyelem *el)
240*1c60b9acSAndroid Build Coastguard Worker {
241*1c60b9acSAndroid Build Coastguard Worker 	const struct lws_ec_curves *curve;
242*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecdsa_context ecdsa;
243*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecp_keypair *kp;
244*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi *mpi[3];
245*1c60b9acSAndroid Build Coastguard Worker 	int n;
246*1c60b9acSAndroid Build Coastguard Worker 
247*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->genec_alg != LEGENEC_ECDH)
248*1c60b9acSAndroid Build Coastguard Worker 		return -1;
249*1c60b9acSAndroid Build Coastguard Worker 
250*1c60b9acSAndroid Build Coastguard Worker 	curve = lws_genec_curve(ctx->curve_table, curve_name);
251*1c60b9acSAndroid Build Coastguard Worker 	if (!curve) {
252*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: curve '%s' not supported\n",
253*1c60b9acSAndroid Build Coastguard Worker 			 __func__, curve_name);
254*1c60b9acSAndroid Build Coastguard Worker 
255*1c60b9acSAndroid Build Coastguard Worker 		return -22;
256*1c60b9acSAndroid Build Coastguard Worker 	}
257*1c60b9acSAndroid Build Coastguard Worker 
258*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecdsa_init(&ecdsa);
259*1c60b9acSAndroid Build Coastguard Worker 	n = mbedtls_ecdsa_genkey(&ecdsa, (mbedtls_ecp_group_id)curve->tls_lib_nid,
260*1c60b9acSAndroid Build Coastguard Worker 				 lws_gencrypto_mbedtls_rngf,
261*1c60b9acSAndroid Build Coastguard Worker 				 ctx->context);
262*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
263*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("mbedtls_ecdsa_genkey failed 0x%x\n", -n);
264*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
265*1c60b9acSAndroid Build Coastguard Worker 	}
266*1c60b9acSAndroid Build Coastguard Worker 
267*1c60b9acSAndroid Build Coastguard Worker 	kp = (mbedtls_ecp_keypair *)&ecdsa;
268*1c60b9acSAndroid Build Coastguard Worker 
269*1c60b9acSAndroid Build Coastguard Worker 	n = mbedtls_ecdh_get_params(ctx->u.ctx_ecdh, kp,
270*1c60b9acSAndroid Build Coastguard Worker 				    (mbedtls_ecdh_side)side);
271*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
272*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("mbedtls_ecdh_get_params failed 0x%x\n", -n);
273*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
274*1c60b9acSAndroid Build Coastguard Worker 	}
275*1c60b9acSAndroid Build Coastguard Worker 
276*1c60b9acSAndroid Build Coastguard Worker 	/*
277*1c60b9acSAndroid Build Coastguard Worker 	 * we need to capture the individual element BIGNUMs into
278*1c60b9acSAndroid Build Coastguard Worker 	 * lws_gencrypto_keyelem, so they can be serialized, used in jwk etc
279*1c60b9acSAndroid Build Coastguard Worker 	 */
280*1c60b9acSAndroid Build Coastguard Worker 
281*1c60b9acSAndroid Build Coastguard Worker 	mpi[0] = &kp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X);
282*1c60b9acSAndroid Build Coastguard Worker 	mpi[1] = &kp->MBEDTLS_PRIVATE(d);
283*1c60b9acSAndroid Build Coastguard Worker 	mpi[2] = &kp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y);
284*1c60b9acSAndroid Build Coastguard Worker 
285*1c60b9acSAndroid Build Coastguard Worker 	el[LWS_GENCRYPTO_EC_KEYEL_CRV].len = (uint32_t)strlen(curve_name) + 1;
286*1c60b9acSAndroid Build Coastguard Worker 	el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf =
287*1c60b9acSAndroid Build Coastguard Worker 			lws_malloc(el[LWS_GENCRYPTO_EC_KEYEL_CRV].len, "ec");
288*1c60b9acSAndroid Build Coastguard Worker 	if (!el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf)
289*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
290*1c60b9acSAndroid Build Coastguard Worker 	strcpy((char *)el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf, curve_name);
291*1c60b9acSAndroid Build Coastguard Worker 
292*1c60b9acSAndroid Build Coastguard Worker 	for (n = LWS_GENCRYPTO_EC_KEYEL_X; n < LWS_GENCRYPTO_EC_KEYEL_COUNT;
293*1c60b9acSAndroid Build Coastguard Worker 	     n++) {
294*1c60b9acSAndroid Build Coastguard Worker 		el[n].len = curve->key_bytes;
295*1c60b9acSAndroid Build Coastguard Worker 		el[n].buf = lws_malloc(curve->key_bytes, "ec");
296*1c60b9acSAndroid Build Coastguard Worker 		if (!el[n].buf)
297*1c60b9acSAndroid Build Coastguard Worker 			goto bail2;
298*1c60b9acSAndroid Build Coastguard Worker 
299*1c60b9acSAndroid Build Coastguard Worker 		if (mbedtls_mpi_write_binary(mpi[n - 1], el[n].buf,
300*1c60b9acSAndroid Build Coastguard Worker 					     curve->key_bytes))
301*1c60b9acSAndroid Build Coastguard Worker 			goto bail2;
302*1c60b9acSAndroid Build Coastguard Worker 	}
303*1c60b9acSAndroid Build Coastguard Worker 
304*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecdsa_free(&ecdsa);
305*1c60b9acSAndroid Build Coastguard Worker 
306*1c60b9acSAndroid Build Coastguard Worker 	return 0;
307*1c60b9acSAndroid Build Coastguard Worker 
308*1c60b9acSAndroid Build Coastguard Worker bail2:
309*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < LWS_GENCRYPTO_EC_KEYEL_COUNT; n++)
310*1c60b9acSAndroid Build Coastguard Worker 		if (el[n].buf)
311*1c60b9acSAndroid Build Coastguard Worker 			lws_free_set_NULL(el[n].buf);
312*1c60b9acSAndroid Build Coastguard Worker bail1:
313*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecdsa_free(&ecdsa);
314*1c60b9acSAndroid Build Coastguard Worker 
315*1c60b9acSAndroid Build Coastguard Worker 	lws_free_set_NULL(ctx->u.ctx_ecdh);
316*1c60b9acSAndroid Build Coastguard Worker 
317*1c60b9acSAndroid Build Coastguard Worker 	return -1;
318*1c60b9acSAndroid Build Coastguard Worker }
319*1c60b9acSAndroid Build Coastguard Worker 
320*1c60b9acSAndroid Build Coastguard Worker int
lws_genecdsa_new_keypair(struct lws_genec_ctx * ctx,const char * curve_name,struct lws_gencrypto_keyelem * el)321*1c60b9acSAndroid Build Coastguard Worker lws_genecdsa_new_keypair(struct lws_genec_ctx *ctx, const char *curve_name,
322*1c60b9acSAndroid Build Coastguard Worker 			 struct lws_gencrypto_keyelem *el)
323*1c60b9acSAndroid Build Coastguard Worker {
324*1c60b9acSAndroid Build Coastguard Worker 	const struct lws_ec_curves *curve;
325*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_ecp_keypair *kp;
326*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi *mpi[3];
327*1c60b9acSAndroid Build Coastguard Worker 	int n;
328*1c60b9acSAndroid Build Coastguard Worker 
329*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->genec_alg != LEGENEC_ECDSA)
330*1c60b9acSAndroid Build Coastguard Worker 		return -1;
331*1c60b9acSAndroid Build Coastguard Worker 
332*1c60b9acSAndroid Build Coastguard Worker 	curve = lws_genec_curve(ctx->curve_table, curve_name);
333*1c60b9acSAndroid Build Coastguard Worker 	if (!curve) {
334*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: curve '%s' not supported\n",
335*1c60b9acSAndroid Build Coastguard Worker 			 __func__, curve_name);
336*1c60b9acSAndroid Build Coastguard Worker 
337*1c60b9acSAndroid Build Coastguard Worker 		return -22;
338*1c60b9acSAndroid Build Coastguard Worker 	}
339*1c60b9acSAndroid Build Coastguard Worker 
340*1c60b9acSAndroid Build Coastguard Worker 	//mbedtls_ecdsa_init(ctx->u.ctx_ecdsa);
341*1c60b9acSAndroid Build Coastguard Worker 	n = mbedtls_ecdsa_genkey(ctx->u.ctx_ecdsa, (mbedtls_ecp_group_id)curve->tls_lib_nid,
342*1c60b9acSAndroid Build Coastguard Worker 				 lws_gencrypto_mbedtls_rngf, ctx->context);
343*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
344*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("mbedtls_ecdsa_genkey failed 0x%x\n", -n);
345*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
346*1c60b9acSAndroid Build Coastguard Worker 	}
347*1c60b9acSAndroid Build Coastguard Worker 
348*1c60b9acSAndroid Build Coastguard Worker 	/*
349*1c60b9acSAndroid Build Coastguard Worker 	 * we need to capture the individual element BIGNUMs into
350*1c60b9acSAndroid Build Coastguard Worker 	 * lws_gencrypto_keyelems, so they can be serialized, used in jwk etc
351*1c60b9acSAndroid Build Coastguard Worker 	 */
352*1c60b9acSAndroid Build Coastguard Worker 
353*1c60b9acSAndroid Build Coastguard Worker 	kp = (mbedtls_ecp_keypair *)ctx->u.ctx_ecdsa;
354*1c60b9acSAndroid Build Coastguard Worker 
355*1c60b9acSAndroid Build Coastguard Worker 	mpi[0] = &kp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X);
356*1c60b9acSAndroid Build Coastguard Worker 	mpi[1] = &kp->MBEDTLS_PRIVATE(d);
357*1c60b9acSAndroid Build Coastguard Worker 	mpi[2] = &kp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y);
358*1c60b9acSAndroid Build Coastguard Worker 
359*1c60b9acSAndroid Build Coastguard Worker 	el[LWS_GENCRYPTO_EC_KEYEL_CRV].len = (uint32_t)strlen(curve_name) + 1;
360*1c60b9acSAndroid Build Coastguard Worker 	el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf =
361*1c60b9acSAndroid Build Coastguard Worker 			lws_malloc(el[LWS_GENCRYPTO_EC_KEYEL_CRV].len, "ec");
362*1c60b9acSAndroid Build Coastguard Worker 	if (!el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf)
363*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
364*1c60b9acSAndroid Build Coastguard Worker 	strcpy((char *)el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf, curve_name);
365*1c60b9acSAndroid Build Coastguard Worker 
366*1c60b9acSAndroid Build Coastguard Worker 	for (n = LWS_GENCRYPTO_EC_KEYEL_X; n < LWS_GENCRYPTO_EC_KEYEL_COUNT;
367*1c60b9acSAndroid Build Coastguard Worker 	     n++) {
368*1c60b9acSAndroid Build Coastguard Worker 		el[n].len = curve->key_bytes;
369*1c60b9acSAndroid Build Coastguard Worker 		el[n].buf = lws_malloc(curve->key_bytes, "ec");
370*1c60b9acSAndroid Build Coastguard Worker 		if (!el[n].buf)
371*1c60b9acSAndroid Build Coastguard Worker 			goto bail2;
372*1c60b9acSAndroid Build Coastguard Worker 
373*1c60b9acSAndroid Build Coastguard Worker 
374*1c60b9acSAndroid Build Coastguard Worker 		if (mbedtls_mpi_write_binary(mpi[n - 1], el[n].buf, el[n].len)) {
375*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: mbedtls_mpi_write_binary failed\n", __func__);
376*1c60b9acSAndroid Build Coastguard Worker 			goto bail2;
377*1c60b9acSAndroid Build Coastguard Worker 		}
378*1c60b9acSAndroid Build Coastguard Worker 	}
379*1c60b9acSAndroid Build Coastguard Worker 
380*1c60b9acSAndroid Build Coastguard Worker 	return 0;
381*1c60b9acSAndroid Build Coastguard Worker 
382*1c60b9acSAndroid Build Coastguard Worker bail2:
383*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < LWS_GENCRYPTO_EC_KEYEL_COUNT; n++)
384*1c60b9acSAndroid Build Coastguard Worker 		if (el[n].buf)
385*1c60b9acSAndroid Build Coastguard Worker 			lws_free_set_NULL(el[n].buf);
386*1c60b9acSAndroid Build Coastguard Worker bail1:
387*1c60b9acSAndroid Build Coastguard Worker 
388*1c60b9acSAndroid Build Coastguard Worker 	lws_free_set_NULL(ctx->u.ctx_ecdsa);
389*1c60b9acSAndroid Build Coastguard Worker 
390*1c60b9acSAndroid Build Coastguard Worker 	return -1;
391*1c60b9acSAndroid Build Coastguard Worker }
392*1c60b9acSAndroid Build Coastguard Worker 
393*1c60b9acSAndroid Build Coastguard Worker 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)394*1c60b9acSAndroid Build Coastguard Worker lws_genecdsa_hash_sign_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
395*1c60b9acSAndroid Build Coastguard Worker 			   enum lws_genhash_types hash_type, int keybits,
396*1c60b9acSAndroid Build Coastguard Worker 			   uint8_t *sig, size_t sig_len)
397*1c60b9acSAndroid Build Coastguard Worker {
398*1c60b9acSAndroid Build Coastguard Worker 	int n, keybytes = lws_gencrypto_bits_to_bytes(keybits);
399*1c60b9acSAndroid Build Coastguard Worker 	size_t hlen = lws_genhash_size(hash_type);
400*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi mpi_r, mpi_s;
401*1c60b9acSAndroid Build Coastguard Worker 	size_t slen = sig_len;
402*1c60b9acSAndroid Build Coastguard Worker 
403*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->genec_alg != LEGENEC_ECDSA)
404*1c60b9acSAndroid Build Coastguard Worker 		return -1;
405*1c60b9acSAndroid Build Coastguard Worker 
406*1c60b9acSAndroid Build Coastguard Worker 	/*
407*1c60b9acSAndroid Build Coastguard Worker 	 * The ECDSA P-256 SHA-256 digital signature is generated as follows:
408*1c60b9acSAndroid Build Coastguard Worker 	 *
409*1c60b9acSAndroid Build Coastguard Worker 	 * 1.  Generate a digital signature of the JWS Signing Input using ECDSA
410*1c60b9acSAndroid Build Coastguard Worker 	 *     P-256 SHA-256 with the desired private key.  The output will be
411*1c60b9acSAndroid Build Coastguard Worker 	 *     the pair (R, S), where R and S are 256-bit unsigned integers.
412*1c60b9acSAndroid Build Coastguard Worker 	 *
413*1c60b9acSAndroid Build Coastguard Worker 	 * 2.  Turn R and S into octet sequences in big-endian order, with each
414*1c60b9acSAndroid Build Coastguard Worker 	 *     array being be 32 octets long.  The octet sequence
415*1c60b9acSAndroid Build Coastguard Worker 	 *     representations MUST NOT be shortened to omit any leading zero
416*1c60b9acSAndroid Build Coastguard Worker 	 *     octets contained in the values.
417*1c60b9acSAndroid Build Coastguard Worker 	 *
418*1c60b9acSAndroid Build Coastguard Worker 	 * 3.  Concatenate the two octet sequences in the order R and then S.
419*1c60b9acSAndroid Build Coastguard Worker 	 *     (Note that many ECDSA implementations will directly produce this
420*1c60b9acSAndroid Build Coastguard Worker 	 *     concatenation as their output.)
421*1c60b9acSAndroid Build Coastguard Worker 	 *
422*1c60b9acSAndroid Build Coastguard Worker 	 * 4.  The resulting 64-octet sequence is the JWS Signature value.
423*1c60b9acSAndroid Build Coastguard Worker 	 */
424*1c60b9acSAndroid Build Coastguard Worker 
425*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_init(&mpi_r);
426*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_init(&mpi_s);
427*1c60b9acSAndroid Build Coastguard Worker 
428*1c60b9acSAndroid Build Coastguard Worker 	n = mbedtls_ecdsa_sign(&ECDSACTX(ctx, grp), &mpi_r, &mpi_s,
429*1c60b9acSAndroid Build Coastguard Worker 			       &ECDSACTX(ctx, d), in, hlen,
430*1c60b9acSAndroid Build Coastguard Worker 			lws_gencrypto_mbedtls_rngf, ctx->context);
431*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
432*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: mbedtls_ecdsa_sign failed: -0x%x\n",
433*1c60b9acSAndroid Build Coastguard Worker 			 __func__, -n);
434*1c60b9acSAndroid Build Coastguard Worker 
435*1c60b9acSAndroid Build Coastguard Worker 		goto bail2;
436*1c60b9acSAndroid Build Coastguard Worker 	}
437*1c60b9acSAndroid Build Coastguard Worker 
438*1c60b9acSAndroid Build Coastguard Worker 	if (mbedtls_mpi_write_binary(&mpi_r, sig, (unsigned int)keybytes))
439*1c60b9acSAndroid Build Coastguard Worker 		goto bail2;
440*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_free(&mpi_r);
441*1c60b9acSAndroid Build Coastguard Worker 	if (mbedtls_mpi_write_binary(&mpi_s, sig + keybytes, (unsigned int)keybytes))
442*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
443*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_free(&mpi_s);
444*1c60b9acSAndroid Build Coastguard Worker 
445*1c60b9acSAndroid Build Coastguard Worker 	return (int)slen;
446*1c60b9acSAndroid Build Coastguard Worker 
447*1c60b9acSAndroid Build Coastguard Worker bail2:
448*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_free(&mpi_r);
449*1c60b9acSAndroid Build Coastguard Worker bail1:
450*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_free(&mpi_s);
451*1c60b9acSAndroid Build Coastguard Worker 
452*1c60b9acSAndroid Build Coastguard Worker 	return -3;
453*1c60b9acSAndroid Build Coastguard Worker }
454*1c60b9acSAndroid Build Coastguard Worker 
455*1c60b9acSAndroid Build Coastguard Worker 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)456*1c60b9acSAndroid Build Coastguard Worker lws_genecdsa_hash_sig_verify_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
457*1c60b9acSAndroid Build Coastguard Worker 				 enum lws_genhash_types hash_type, int keybits,
458*1c60b9acSAndroid Build Coastguard Worker 				 const uint8_t *sig, size_t sig_len)
459*1c60b9acSAndroid Build Coastguard Worker {
460*1c60b9acSAndroid Build Coastguard Worker 	int n, keybytes = lws_gencrypto_bits_to_bytes(keybits);
461*1c60b9acSAndroid Build Coastguard Worker 	size_t hlen = lws_genhash_size(hash_type);
462*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi mpi_r, mpi_s;
463*1c60b9acSAndroid Build Coastguard Worker 
464*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->genec_alg != LEGENEC_ECDSA)
465*1c60b9acSAndroid Build Coastguard Worker 		return -1;
466*1c60b9acSAndroid Build Coastguard Worker 
467*1c60b9acSAndroid Build Coastguard Worker 	if ((int)sig_len != keybytes * 2)
468*1c60b9acSAndroid Build Coastguard Worker 		return -1;
469*1c60b9acSAndroid Build Coastguard Worker 
470*1c60b9acSAndroid Build Coastguard Worker 	/*
471*1c60b9acSAndroid Build Coastguard Worker 	 * 1.  The JWS Signature value MUST be a 64-octet sequence.  If it is
472*1c60b9acSAndroid Build Coastguard Worker 	 *     not a 64-octet sequence, the validation has failed.
473*1c60b9acSAndroid Build Coastguard Worker 	 *
474*1c60b9acSAndroid Build Coastguard Worker 	 * 2.  Split the 64-octet sequence into two 32-octet sequences.  The
475*1c60b9acSAndroid Build Coastguard Worker 	 *     first octet sequence represents R and the second S.  The values R
476*1c60b9acSAndroid Build Coastguard Worker 	 *     and S are represented as octet sequences using the Integer-to-
477*1c60b9acSAndroid Build Coastguard Worker 	 *     OctetString Conversion defined in Section 2.3.7 of SEC1 [SEC1]
478*1c60b9acSAndroid Build Coastguard Worker 	 *     (in big-endian octet order).
479*1c60b9acSAndroid Build Coastguard Worker 	 *
480*1c60b9acSAndroid Build Coastguard Worker 	 * 3.  Submit the JWS Signing Input, R, S, and the public key (x, y) to
481*1c60b9acSAndroid Build Coastguard Worker 	 *     the ECDSA P-256 SHA-256 validator.
482*1c60b9acSAndroid Build Coastguard Worker 	 */
483*1c60b9acSAndroid Build Coastguard Worker 
484*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_init(&mpi_r);
485*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_init(&mpi_s);
486*1c60b9acSAndroid Build Coastguard Worker 
487*1c60b9acSAndroid Build Coastguard Worker 	if (mbedtls_mpi_read_binary(&mpi_r, sig, (unsigned int)keybytes))
488*1c60b9acSAndroid Build Coastguard Worker 		return -1;
489*1c60b9acSAndroid Build Coastguard Worker 	if (mbedtls_mpi_read_binary(&mpi_s, sig + keybytes, (unsigned int)keybytes))
490*1c60b9acSAndroid Build Coastguard Worker 		goto bail1;
491*1c60b9acSAndroid Build Coastguard Worker 
492*1c60b9acSAndroid Build Coastguard Worker 	n = mbedtls_ecdsa_verify(&ECDSACTX(ctx, grp), in, hlen,
493*1c60b9acSAndroid Build Coastguard Worker 				 &ECDSACTX(ctx, Q), &mpi_r, &mpi_s);
494*1c60b9acSAndroid Build Coastguard Worker 
495*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_free(&mpi_s);
496*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_free(&mpi_r);
497*1c60b9acSAndroid Build Coastguard Worker 
498*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
499*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: mbedtls_ecdsa_verify failed: -0x%x\n",
500*1c60b9acSAndroid Build Coastguard Worker 			 __func__, -n);
501*1c60b9acSAndroid Build Coastguard Worker 
502*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
503*1c60b9acSAndroid Build Coastguard Worker 	}
504*1c60b9acSAndroid Build Coastguard Worker 
505*1c60b9acSAndroid Build Coastguard Worker 	return 0;
506*1c60b9acSAndroid Build Coastguard Worker bail1:
507*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi_free(&mpi_r);
508*1c60b9acSAndroid Build Coastguard Worker 
509*1c60b9acSAndroid Build Coastguard Worker bail:
510*1c60b9acSAndroid Build Coastguard Worker 
511*1c60b9acSAndroid Build Coastguard Worker 	return -3;
512*1c60b9acSAndroid Build Coastguard Worker }
513*1c60b9acSAndroid Build Coastguard Worker 
514*1c60b9acSAndroid Build Coastguard Worker int
lws_genecdh_compute_shared_secret(struct lws_genec_ctx * ctx,uint8_t * ss,int * ss_len)515*1c60b9acSAndroid Build Coastguard Worker lws_genecdh_compute_shared_secret(struct lws_genec_ctx *ctx, uint8_t *ss,
516*1c60b9acSAndroid Build Coastguard Worker 				  int *ss_len)
517*1c60b9acSAndroid Build Coastguard Worker {
518*1c60b9acSAndroid Build Coastguard Worker 	int n;
519*1c60b9acSAndroid Build Coastguard Worker 	size_t st;
520*1c60b9acSAndroid Build Coastguard Worker 	if (mbedtls_ecp_check_pubkey(&ECDHCTX(ctx, grp), &ECDHCTX(ctx, Q)) ||
521*1c60b9acSAndroid Build Coastguard Worker 	    mbedtls_ecp_check_pubkey(&ECDHCTX(ctx, grp), &ECDHCTX(ctx, Qp))) {
522*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: both sides must be set up\n", __func__);
523*1c60b9acSAndroid Build Coastguard Worker 
524*1c60b9acSAndroid Build Coastguard Worker 		return -1;
525*1c60b9acSAndroid Build Coastguard Worker 	}
526*1c60b9acSAndroid Build Coastguard Worker 
527*1c60b9acSAndroid Build Coastguard Worker 	n = mbedtls_ecdh_calc_secret(ctx->u.ctx_ecdh, &st, ss, (size_t)*ss_len,
528*1c60b9acSAndroid Build Coastguard Worker 			lws_gencrypto_mbedtls_rngf, ctx->context);
529*1c60b9acSAndroid Build Coastguard Worker 	if (n)
530*1c60b9acSAndroid Build Coastguard Worker 		return -1;
531*1c60b9acSAndroid Build Coastguard Worker 
532*1c60b9acSAndroid Build Coastguard Worker 	*ss_len = (int)st;
533*1c60b9acSAndroid Build Coastguard Worker 
534*1c60b9acSAndroid Build Coastguard Worker 	return 0;
535*1c60b9acSAndroid Build Coastguard Worker }
536