xref: /aosp_15_r20/external/libwebsockets/lib/tls/mbedtls/lws-genrsa.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_genrsa provides an RSA 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 #include <mbedtls/rsa.h>
30*1c60b9acSAndroid Build Coastguard Worker 
31*1c60b9acSAndroid Build Coastguard Worker void
lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem * el)32*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem *el)
33*1c60b9acSAndroid Build Coastguard Worker {
34*1c60b9acSAndroid Build Coastguard Worker 	int n;
35*1c60b9acSAndroid Build Coastguard Worker 
36*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
37*1c60b9acSAndroid Build Coastguard Worker 		if (el[n].buf)
38*1c60b9acSAndroid Build Coastguard Worker 			lws_free_set_NULL(el[n].buf);
39*1c60b9acSAndroid Build Coastguard Worker }
40*1c60b9acSAndroid Build Coastguard Worker 
41*1c60b9acSAndroid Build Coastguard Worker static int mode_map[] = { MBEDTLS_RSA_PKCS_V15, MBEDTLS_RSA_PKCS_V21 };
42*1c60b9acSAndroid Build Coastguard Worker 
43*1c60b9acSAndroid Build Coastguard Worker int
lws_genrsa_create(struct lws_genrsa_ctx * ctx,const struct lws_gencrypto_keyelem * el,struct lws_context * context,enum enum_genrsa_mode mode,enum lws_genhash_types oaep_hashid)44*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_create(struct lws_genrsa_ctx *ctx,
45*1c60b9acSAndroid Build Coastguard Worker 		  const struct lws_gencrypto_keyelem *el,
46*1c60b9acSAndroid Build Coastguard Worker 		  struct lws_context *context, enum enum_genrsa_mode mode,
47*1c60b9acSAndroid Build Coastguard Worker 		  enum lws_genhash_types oaep_hashid)
48*1c60b9acSAndroid Build Coastguard Worker {
49*1c60b9acSAndroid Build Coastguard Worker 	memset(ctx, 0, sizeof(*ctx));
50*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx = lws_zalloc(sizeof(*ctx->ctx), "genrsa");
51*1c60b9acSAndroid Build Coastguard Worker 	if (!ctx->ctx)
52*1c60b9acSAndroid Build Coastguard Worker 		return 1;
53*1c60b9acSAndroid Build Coastguard Worker 
54*1c60b9acSAndroid Build Coastguard Worker 	ctx->context = context;
55*1c60b9acSAndroid Build Coastguard Worker 	ctx->mode = mode;
56*1c60b9acSAndroid Build Coastguard Worker 
57*1c60b9acSAndroid Build Coastguard Worker 	if (mode >= LGRSAM_COUNT)
58*1c60b9acSAndroid Build Coastguard Worker 		return -1;
59*1c60b9acSAndroid Build Coastguard Worker 
60*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
61*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_init(ctx->ctx, mode_map[mode], 0);
62*1c60b9acSAndroid Build Coastguard Worker #else
63*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_init(ctx->ctx);
64*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_set_padding(ctx->ctx, mode_map[mode], 0);
65*1c60b9acSAndroid Build Coastguard Worker #endif
66*1c60b9acSAndroid Build Coastguard Worker 
67*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx->MBEDTLS_PRIVATE(padding) = mode_map[mode];
68*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx->MBEDTLS_PRIVATE(hash_id) =
69*1c60b9acSAndroid Build Coastguard Worker 			(int)lws_gencrypto_mbedtls_hash_to_MD_TYPE(oaep_hashid);
70*1c60b9acSAndroid Build Coastguard Worker 
71*1c60b9acSAndroid Build Coastguard Worker 	{
72*1c60b9acSAndroid Build Coastguard Worker 		int n;
73*1c60b9acSAndroid Build Coastguard Worker 
74*1c60b9acSAndroid Build Coastguard Worker 		mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT] = {
75*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(E),
76*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(N),
77*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(D),
78*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(P),
79*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(Q),
80*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(DP),
81*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(DQ),
82*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(QP),
83*1c60b9acSAndroid Build Coastguard Worker 		};
84*1c60b9acSAndroid Build Coastguard Worker 
85*1c60b9acSAndroid Build Coastguard Worker 		for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
86*1c60b9acSAndroid Build Coastguard Worker 			if (el[n].buf &&
87*1c60b9acSAndroid Build Coastguard Worker 			    mbedtls_mpi_read_binary(mpi[n], el[n].buf,
88*1c60b9acSAndroid Build Coastguard Worker 					    	    el[n].len)) {
89*1c60b9acSAndroid Build Coastguard Worker 				lwsl_notice("mpi load failed\n");
90*1c60b9acSAndroid Build Coastguard Worker 				lws_free_set_NULL(ctx->ctx);
91*1c60b9acSAndroid Build Coastguard Worker 
92*1c60b9acSAndroid Build Coastguard Worker 				return -1;
93*1c60b9acSAndroid Build Coastguard Worker 			}
94*1c60b9acSAndroid Build Coastguard Worker 
95*1c60b9acSAndroid Build Coastguard Worker 		/* mbedtls... compute missing P & Q */
96*1c60b9acSAndroid Build Coastguard Worker 
97*1c60b9acSAndroid Build Coastguard Worker 		if ( el[LWS_GENCRYPTO_RSA_KEYEL_D].len &&
98*1c60b9acSAndroid Build Coastguard Worker 		    !el[LWS_GENCRYPTO_RSA_KEYEL_P].len &&
99*1c60b9acSAndroid Build Coastguard Worker 		    !el[LWS_GENCRYPTO_RSA_KEYEL_Q].len) {
100*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_mbedtls_rsa_complete)
101*1c60b9acSAndroid Build Coastguard Worker 			if (mbedtls_rsa_complete(ctx->ctx)) {
102*1c60b9acSAndroid Build Coastguard Worker 				lwsl_notice("mbedtls_rsa_complete failed\n");
103*1c60b9acSAndroid Build Coastguard Worker #else
104*1c60b9acSAndroid Build Coastguard Worker 			{
105*1c60b9acSAndroid Build Coastguard Worker 				lwsl_notice("%s: you have to provide P and Q\n", __func__);
106*1c60b9acSAndroid Build Coastguard Worker #endif
107*1c60b9acSAndroid Build Coastguard Worker 				lws_free_set_NULL(ctx->ctx);
108*1c60b9acSAndroid Build Coastguard Worker 
109*1c60b9acSAndroid Build Coastguard Worker 				return -1;
110*1c60b9acSAndroid Build Coastguard Worker 			}
111*1c60b9acSAndroid Build Coastguard Worker 
112*1c60b9acSAndroid Build Coastguard Worker 		}
113*1c60b9acSAndroid Build Coastguard Worker 	}
114*1c60b9acSAndroid Build Coastguard Worker 
115*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx->MBEDTLS_PRIVATE(len) = el[LWS_GENCRYPTO_RSA_KEYEL_N].len;
116*1c60b9acSAndroid Build Coastguard Worker 
117*1c60b9acSAndroid Build Coastguard Worker 	return 0;
118*1c60b9acSAndroid Build Coastguard Worker }
119*1c60b9acSAndroid Build Coastguard Worker 
120*1c60b9acSAndroid Build Coastguard Worker static int
121*1c60b9acSAndroid Build Coastguard Worker _rngf(void *context, unsigned char *buf, size_t len)
122*1c60b9acSAndroid Build Coastguard Worker {
123*1c60b9acSAndroid Build Coastguard Worker 	if ((size_t)lws_get_random(context, buf, len) == len)
124*1c60b9acSAndroid Build Coastguard Worker 		return 0;
125*1c60b9acSAndroid Build Coastguard Worker 
126*1c60b9acSAndroid Build Coastguard Worker 	return -1;
127*1c60b9acSAndroid Build Coastguard Worker }
128*1c60b9acSAndroid Build Coastguard Worker 
129*1c60b9acSAndroid Build Coastguard Worker int
130*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx *ctx,
131*1c60b9acSAndroid Build Coastguard Worker 		       enum enum_genrsa_mode mode, struct lws_gencrypto_keyelem *el,
132*1c60b9acSAndroid Build Coastguard Worker 		       int bits)
133*1c60b9acSAndroid Build Coastguard Worker {
134*1c60b9acSAndroid Build Coastguard Worker 	int n;
135*1c60b9acSAndroid Build Coastguard Worker 
136*1c60b9acSAndroid Build Coastguard Worker 	memset(ctx, 0, sizeof(*ctx));
137*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx = lws_zalloc(sizeof(*ctx->ctx), "genrsa");
138*1c60b9acSAndroid Build Coastguard Worker 	if (!ctx->ctx)
139*1c60b9acSAndroid Build Coastguard Worker 		return -1;
140*1c60b9acSAndroid Build Coastguard Worker 
141*1c60b9acSAndroid Build Coastguard Worker 	ctx->context = context;
142*1c60b9acSAndroid Build Coastguard Worker 	ctx->mode = mode;
143*1c60b9acSAndroid Build Coastguard Worker 
144*1c60b9acSAndroid Build Coastguard Worker 	if (mode >= LGRSAM_COUNT)
145*1c60b9acSAndroid Build Coastguard Worker 		return -1;
146*1c60b9acSAndroid Build Coastguard Worker 
147*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
148*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_init(ctx->ctx, mode_map[mode], 0);
149*1c60b9acSAndroid Build Coastguard Worker #else
150*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_init(ctx->ctx);
151*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_set_padding(ctx->ctx, mode_map[mode], 0);
152*1c60b9acSAndroid Build Coastguard Worker #endif
153*1c60b9acSAndroid Build Coastguard Worker 
154*1c60b9acSAndroid Build Coastguard Worker 	n = mbedtls_rsa_gen_key(ctx->ctx, _rngf, context, (unsigned int)bits, 65537);
155*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
156*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("mbedtls_rsa_gen_key failed 0x%x\n", -n);
157*1c60b9acSAndroid Build Coastguard Worker 		goto cleanup_1;
158*1c60b9acSAndroid Build Coastguard Worker 	}
159*1c60b9acSAndroid Build Coastguard Worker 
160*1c60b9acSAndroid Build Coastguard Worker 	{
161*1c60b9acSAndroid Build Coastguard Worker 		mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT] = {
162*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(E),
163*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(N),
164*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(D),
165*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(P),
166*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(Q),
167*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(DP),
168*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(DQ),
169*1c60b9acSAndroid Build Coastguard Worker 			&ctx->ctx->MBEDTLS_PRIVATE(QP),
170*1c60b9acSAndroid Build Coastguard Worker 		};
171*1c60b9acSAndroid Build Coastguard Worker 
172*1c60b9acSAndroid Build Coastguard Worker 		for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
173*1c60b9acSAndroid Build Coastguard Worker 			if (mpi[n] && mbedtls_mpi_size(mpi[n])) {
174*1c60b9acSAndroid Build Coastguard Worker 				el[n].buf = lws_malloc(
175*1c60b9acSAndroid Build Coastguard Worker 					mbedtls_mpi_size(mpi[n]), "genrsakey");
176*1c60b9acSAndroid Build Coastguard Worker 				if (!el[n].buf)
177*1c60b9acSAndroid Build Coastguard Worker 					goto cleanup;
178*1c60b9acSAndroid Build Coastguard Worker 				el[n].len = (uint32_t)mbedtls_mpi_size(mpi[n]);
179*1c60b9acSAndroid Build Coastguard Worker 				if (mbedtls_mpi_write_binary(mpi[n], el[n].buf,
180*1c60b9acSAndroid Build Coastguard Worker 							 el[n].len))
181*1c60b9acSAndroid Build Coastguard Worker 					goto cleanup;
182*1c60b9acSAndroid Build Coastguard Worker 			}
183*1c60b9acSAndroid Build Coastguard Worker 	}
184*1c60b9acSAndroid Build Coastguard Worker 
185*1c60b9acSAndroid Build Coastguard Worker 	return 0;
186*1c60b9acSAndroid Build Coastguard Worker 
187*1c60b9acSAndroid Build Coastguard Worker cleanup:
188*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
189*1c60b9acSAndroid Build Coastguard Worker 		if (el[n].buf)
190*1c60b9acSAndroid Build Coastguard Worker 			lws_free_set_NULL(el[n].buf);
191*1c60b9acSAndroid Build Coastguard Worker cleanup_1:
192*1c60b9acSAndroid Build Coastguard Worker 	lws_free(ctx->ctx);
193*1c60b9acSAndroid Build Coastguard Worker 
194*1c60b9acSAndroid Build Coastguard Worker 	return -1;
195*1c60b9acSAndroid Build Coastguard Worker }
196*1c60b9acSAndroid Build Coastguard Worker 
197*1c60b9acSAndroid Build Coastguard Worker int
198*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
199*1c60b9acSAndroid Build Coastguard Worker 			  size_t in_len, uint8_t *out, size_t out_max)
200*1c60b9acSAndroid Build Coastguard Worker {
201*1c60b9acSAndroid Build Coastguard Worker 	size_t olen = 0;
202*1c60b9acSAndroid Build Coastguard Worker 	int n;
203*1c60b9acSAndroid Build Coastguard Worker 
204*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx->MBEDTLS_PRIVATE(len) = in_len;
205*1c60b9acSAndroid Build Coastguard Worker 
206*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_mbedtls_rsa_complete)
207*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_complete(ctx->ctx);
208*1c60b9acSAndroid Build Coastguard Worker #endif
209*1c60b9acSAndroid Build Coastguard Worker 
210*1c60b9acSAndroid Build Coastguard Worker 	switch(ctx->mode) {
211*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_1_5:
212*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(ctx->ctx, _rngf,
213*1c60b9acSAndroid Build Coastguard Worker 							ctx->context,
214*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
215*1c60b9acSAndroid Build Coastguard Worker 							MBEDTLS_RSA_PUBLIC,
216*1c60b9acSAndroid Build Coastguard Worker #endif
217*1c60b9acSAndroid Build Coastguard Worker 							&olen, in, out,
218*1c60b9acSAndroid Build Coastguard Worker 							out_max);
219*1c60b9acSAndroid Build Coastguard Worker 		break;
220*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_OAEP_PSS:
221*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsaes_oaep_decrypt(ctx->ctx, _rngf,
222*1c60b9acSAndroid Build Coastguard Worker 						   ctx->context,
223*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
224*1c60b9acSAndroid Build Coastguard Worker 							MBEDTLS_RSA_PUBLIC,
225*1c60b9acSAndroid Build Coastguard Worker #endif
226*1c60b9acSAndroid Build Coastguard Worker 						   NULL, 0,
227*1c60b9acSAndroid Build Coastguard Worker 						   &olen, in, out, out_max);
228*1c60b9acSAndroid Build Coastguard Worker 		break;
229*1c60b9acSAndroid Build Coastguard Worker 	default:
230*1c60b9acSAndroid Build Coastguard Worker 		return -1;
231*1c60b9acSAndroid Build Coastguard Worker 	}
232*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
233*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: -0x%x\n", __func__, -n);
234*1c60b9acSAndroid Build Coastguard Worker 
235*1c60b9acSAndroid Build Coastguard Worker 		return -1;
236*1c60b9acSAndroid Build Coastguard Worker 	}
237*1c60b9acSAndroid Build Coastguard Worker 
238*1c60b9acSAndroid Build Coastguard Worker 	return (int)olen;
239*1c60b9acSAndroid Build Coastguard Worker }
240*1c60b9acSAndroid Build Coastguard Worker 
241*1c60b9acSAndroid Build Coastguard Worker int
242*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_private_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
243*1c60b9acSAndroid Build Coastguard Worker 			   size_t in_len, uint8_t *out, size_t out_max)
244*1c60b9acSAndroid Build Coastguard Worker {
245*1c60b9acSAndroid Build Coastguard Worker 	size_t olen = 0;
246*1c60b9acSAndroid Build Coastguard Worker 	int n;
247*1c60b9acSAndroid Build Coastguard Worker 
248*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx->MBEDTLS_PRIVATE(len) = in_len;
249*1c60b9acSAndroid Build Coastguard Worker 
250*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_mbedtls_rsa_complete)
251*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_complete(ctx->ctx);
252*1c60b9acSAndroid Build Coastguard Worker #endif
253*1c60b9acSAndroid Build Coastguard Worker 
254*1c60b9acSAndroid Build Coastguard Worker 	switch(ctx->mode) {
255*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_1_5:
256*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(ctx->ctx, _rngf,
257*1c60b9acSAndroid Build Coastguard Worker 							ctx->context,
258*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
259*1c60b9acSAndroid Build Coastguard Worker 							MBEDTLS_RSA_PRIVATE,
260*1c60b9acSAndroid Build Coastguard Worker #endif
261*1c60b9acSAndroid Build Coastguard Worker 							&olen, in, out,
262*1c60b9acSAndroid Build Coastguard Worker 							out_max);
263*1c60b9acSAndroid Build Coastguard Worker 		break;
264*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_OAEP_PSS:
265*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsaes_oaep_decrypt(ctx->ctx, _rngf,
266*1c60b9acSAndroid Build Coastguard Worker 						   ctx->context,
267*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
268*1c60b9acSAndroid Build Coastguard Worker 						   MBEDTLS_RSA_PRIVATE,
269*1c60b9acSAndroid Build Coastguard Worker #endif
270*1c60b9acSAndroid Build Coastguard Worker 						   NULL, 0,
271*1c60b9acSAndroid Build Coastguard Worker 						   &olen, in, out, out_max);
272*1c60b9acSAndroid Build Coastguard Worker 		break;
273*1c60b9acSAndroid Build Coastguard Worker 	default:
274*1c60b9acSAndroid Build Coastguard Worker 		return -1;
275*1c60b9acSAndroid Build Coastguard Worker 	}
276*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
277*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: -0x%x\n", __func__, -n);
278*1c60b9acSAndroid Build Coastguard Worker 
279*1c60b9acSAndroid Build Coastguard Worker 		return -1;
280*1c60b9acSAndroid Build Coastguard Worker 	}
281*1c60b9acSAndroid Build Coastguard Worker 
282*1c60b9acSAndroid Build Coastguard Worker 	return (int)olen;
283*1c60b9acSAndroid Build Coastguard Worker }
284*1c60b9acSAndroid Build Coastguard Worker 
285*1c60b9acSAndroid Build Coastguard Worker int
286*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_public_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
287*1c60b9acSAndroid Build Coastguard Worker 			  size_t in_len, uint8_t *out)
288*1c60b9acSAndroid Build Coastguard Worker {
289*1c60b9acSAndroid Build Coastguard Worker 	int n;
290*1c60b9acSAndroid Build Coastguard Worker 
291*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_mbedtls_rsa_complete)
292*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_complete(ctx->ctx);
293*1c60b9acSAndroid Build Coastguard Worker #endif
294*1c60b9acSAndroid Build Coastguard Worker 
295*1c60b9acSAndroid Build Coastguard Worker 	switch(ctx->mode) {
296*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_1_5:
297*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsaes_pkcs1_v15_encrypt(ctx->ctx, _rngf,
298*1c60b9acSAndroid Build Coastguard Worker 							ctx->context,
299*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
300*1c60b9acSAndroid Build Coastguard Worker 							MBEDTLS_RSA_PUBLIC,
301*1c60b9acSAndroid Build Coastguard Worker #endif
302*1c60b9acSAndroid Build Coastguard Worker 							in_len, in, out);
303*1c60b9acSAndroid Build Coastguard Worker 		break;
304*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_OAEP_PSS:
305*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsaes_oaep_encrypt(ctx->ctx, _rngf,
306*1c60b9acSAndroid Build Coastguard Worker 						   ctx->context,
307*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
308*1c60b9acSAndroid Build Coastguard Worker 						   MBEDTLS_RSA_PUBLIC,
309*1c60b9acSAndroid Build Coastguard Worker #endif
310*1c60b9acSAndroid Build Coastguard Worker 						   NULL, 0,
311*1c60b9acSAndroid Build Coastguard Worker 						   in_len, in, out);
312*1c60b9acSAndroid Build Coastguard Worker 		break;
313*1c60b9acSAndroid Build Coastguard Worker 	default:
314*1c60b9acSAndroid Build Coastguard Worker 		return -1;
315*1c60b9acSAndroid Build Coastguard Worker 	}
316*1c60b9acSAndroid Build Coastguard Worker 	if (n < 0) {
317*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: -0x%x: in_len: %d\n", __func__, -n,
318*1c60b9acSAndroid Build Coastguard Worker 				(int)in_len);
319*1c60b9acSAndroid Build Coastguard Worker 
320*1c60b9acSAndroid Build Coastguard Worker 		return -1;
321*1c60b9acSAndroid Build Coastguard Worker 	}
322*1c60b9acSAndroid Build Coastguard Worker 
323*1c60b9acSAndroid Build Coastguard Worker 	return (int)mbedtls_mpi_size(&ctx->ctx->MBEDTLS_PRIVATE(N));
324*1c60b9acSAndroid Build Coastguard Worker }
325*1c60b9acSAndroid Build Coastguard Worker 
326*1c60b9acSAndroid Build Coastguard Worker int
327*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_private_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
328*1c60b9acSAndroid Build Coastguard Worker 			   size_t in_len, uint8_t *out)
329*1c60b9acSAndroid Build Coastguard Worker {
330*1c60b9acSAndroid Build Coastguard Worker 	int n;
331*1c60b9acSAndroid Build Coastguard Worker 
332*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_mbedtls_rsa_complete)
333*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_complete(ctx->ctx);
334*1c60b9acSAndroid Build Coastguard Worker #endif
335*1c60b9acSAndroid Build Coastguard Worker 
336*1c60b9acSAndroid Build Coastguard Worker 	switch(ctx->mode) {
337*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_1_5:
338*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsaes_pkcs1_v15_encrypt(ctx->ctx, _rngf,
339*1c60b9acSAndroid Build Coastguard Worker 							ctx->context,
340*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
341*1c60b9acSAndroid Build Coastguard Worker 							MBEDTLS_RSA_PRIVATE,
342*1c60b9acSAndroid Build Coastguard Worker #endif
343*1c60b9acSAndroid Build Coastguard Worker 							in_len, in, out);
344*1c60b9acSAndroid Build Coastguard Worker 		break;
345*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_OAEP_PSS:
346*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsaes_oaep_encrypt(ctx->ctx, _rngf,
347*1c60b9acSAndroid Build Coastguard Worker 						   ctx->context,
348*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
349*1c60b9acSAndroid Build Coastguard Worker 						   MBEDTLS_RSA_PRIVATE,
350*1c60b9acSAndroid Build Coastguard Worker #endif
351*1c60b9acSAndroid Build Coastguard Worker 						   NULL, 0,
352*1c60b9acSAndroid Build Coastguard Worker 						   in_len, in, out);
353*1c60b9acSAndroid Build Coastguard Worker 		break;
354*1c60b9acSAndroid Build Coastguard Worker 	default:
355*1c60b9acSAndroid Build Coastguard Worker 		return -1;
356*1c60b9acSAndroid Build Coastguard Worker 	}
357*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
358*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: -0x%x: in_len: %d\n", __func__, -n,
359*1c60b9acSAndroid Build Coastguard Worker 				(int)in_len);
360*1c60b9acSAndroid Build Coastguard Worker 
361*1c60b9acSAndroid Build Coastguard Worker 		return -1;
362*1c60b9acSAndroid Build Coastguard Worker 	}
363*1c60b9acSAndroid Build Coastguard Worker 
364*1c60b9acSAndroid Build Coastguard Worker 	return (int)mbedtls_mpi_size(&ctx->ctx->MBEDTLS_PRIVATE(N));
365*1c60b9acSAndroid Build Coastguard Worker }
366*1c60b9acSAndroid Build Coastguard Worker 
367*1c60b9acSAndroid Build Coastguard Worker int
368*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_hash_sig_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in,
369*1c60b9acSAndroid Build Coastguard Worker 			 enum lws_genhash_types hash_type, const uint8_t *sig,
370*1c60b9acSAndroid Build Coastguard Worker 			 size_t sig_len)
371*1c60b9acSAndroid Build Coastguard Worker {
372*1c60b9acSAndroid Build Coastguard Worker 	int n, h = (int)lws_gencrypto_mbedtls_hash_to_MD_TYPE(hash_type);
373*1c60b9acSAndroid Build Coastguard Worker 
374*1c60b9acSAndroid Build Coastguard Worker 	if (h < 0)
375*1c60b9acSAndroid Build Coastguard Worker 		return -1;
376*1c60b9acSAndroid Build Coastguard Worker 
377*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_mbedtls_rsa_complete)
378*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_complete(ctx->ctx);
379*1c60b9acSAndroid Build Coastguard Worker #endif
380*1c60b9acSAndroid Build Coastguard Worker 
381*1c60b9acSAndroid Build Coastguard Worker 	switch(ctx->mode) {
382*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_1_5:
383*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsassa_pkcs1_v15_verify(ctx->ctx,
384*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
385*1c60b9acSAndroid Build Coastguard Worker 							NULL, NULL,
386*1c60b9acSAndroid Build Coastguard Worker 							MBEDTLS_RSA_PUBLIC,
387*1c60b9acSAndroid Build Coastguard Worker #endif
388*1c60b9acSAndroid Build Coastguard Worker 							(mbedtls_md_type_t)h,
389*1c60b9acSAndroid Build Coastguard Worker 							(unsigned int)lws_genhash_size(hash_type),
390*1c60b9acSAndroid Build Coastguard Worker 							in, sig);
391*1c60b9acSAndroid Build Coastguard Worker 		break;
392*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_OAEP_PSS:
393*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsassa_pss_verify(ctx->ctx,
394*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
395*1c60b9acSAndroid Build Coastguard Worker 						  NULL, NULL,
396*1c60b9acSAndroid Build Coastguard Worker 						  MBEDTLS_RSA_PUBLIC,
397*1c60b9acSAndroid Build Coastguard Worker #endif
398*1c60b9acSAndroid Build Coastguard Worker 						  (mbedtls_md_type_t)h,
399*1c60b9acSAndroid Build Coastguard Worker 						  (unsigned int)lws_genhash_size(hash_type),
400*1c60b9acSAndroid Build Coastguard Worker 						  in, sig);
401*1c60b9acSAndroid Build Coastguard Worker 		break;
402*1c60b9acSAndroid Build Coastguard Worker 	default:
403*1c60b9acSAndroid Build Coastguard Worker 		return -1;
404*1c60b9acSAndroid Build Coastguard Worker 	}
405*1c60b9acSAndroid Build Coastguard Worker 	if (n < 0) {
406*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: (mode %d) -0x%x\n", __func__, ctx->mode, -n);
407*1c60b9acSAndroid Build Coastguard Worker 
408*1c60b9acSAndroid Build Coastguard Worker 		return -1;
409*1c60b9acSAndroid Build Coastguard Worker 	}
410*1c60b9acSAndroid Build Coastguard Worker 
411*1c60b9acSAndroid Build Coastguard Worker 	return n;
412*1c60b9acSAndroid Build Coastguard Worker }
413*1c60b9acSAndroid Build Coastguard Worker 
414*1c60b9acSAndroid Build Coastguard Worker int
415*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_hash_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in,
416*1c60b9acSAndroid Build Coastguard Worker 		       enum lws_genhash_types hash_type, uint8_t *sig,
417*1c60b9acSAndroid Build Coastguard Worker 		       size_t sig_len)
418*1c60b9acSAndroid Build Coastguard Worker {
419*1c60b9acSAndroid Build Coastguard Worker 	int n, h = (int)lws_gencrypto_mbedtls_hash_to_MD_TYPE(hash_type);
420*1c60b9acSAndroid Build Coastguard Worker 
421*1c60b9acSAndroid Build Coastguard Worker 	if (h < 0)
422*1c60b9acSAndroid Build Coastguard Worker 		return -1;
423*1c60b9acSAndroid Build Coastguard Worker 
424*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_mbedtls_rsa_complete)
425*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_complete(ctx->ctx);
426*1c60b9acSAndroid Build Coastguard Worker #endif
427*1c60b9acSAndroid Build Coastguard Worker 
428*1c60b9acSAndroid Build Coastguard Worker 	/*
429*1c60b9acSAndroid Build Coastguard Worker 	 * The "sig" buffer must be as large as the size of ctx->N
430*1c60b9acSAndroid Build Coastguard Worker 	 * (eg. 128 bytes if RSA-1024 is used).
431*1c60b9acSAndroid Build Coastguard Worker 	 */
432*1c60b9acSAndroid Build Coastguard Worker 	if (sig_len < ctx->ctx->MBEDTLS_PRIVATE(len))
433*1c60b9acSAndroid Build Coastguard Worker 		return -1;
434*1c60b9acSAndroid Build Coastguard Worker 
435*1c60b9acSAndroid Build Coastguard Worker 	switch(ctx->mode) {
436*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_1_5:
437*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsassa_pkcs1_v15_sign(ctx->ctx,
438*1c60b9acSAndroid Build Coastguard Worker 						      mbedtls_ctr_drbg_random,
439*1c60b9acSAndroid Build Coastguard Worker 						      &ctx->context->mcdc,
440*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
441*1c60b9acSAndroid Build Coastguard Worker 						      MBEDTLS_RSA_PRIVATE,
442*1c60b9acSAndroid Build Coastguard Worker #endif
443*1c60b9acSAndroid Build Coastguard Worker 						      (mbedtls_md_type_t)h,
444*1c60b9acSAndroid Build Coastguard Worker 						      (unsigned int)lws_genhash_size(hash_type),
445*1c60b9acSAndroid Build Coastguard Worker 						      in, sig);
446*1c60b9acSAndroid Build Coastguard Worker 		break;
447*1c60b9acSAndroid Build Coastguard Worker 	case LGRSAM_PKCS1_OAEP_PSS:
448*1c60b9acSAndroid Build Coastguard Worker 		n = mbedtls_rsa_rsassa_pss_sign(ctx->ctx,
449*1c60b9acSAndroid Build Coastguard Worker 						mbedtls_ctr_drbg_random,
450*1c60b9acSAndroid Build Coastguard Worker 						&ctx->context->mcdc,
451*1c60b9acSAndroid Build Coastguard Worker #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03000000
452*1c60b9acSAndroid Build Coastguard Worker 						MBEDTLS_RSA_PRIVATE,
453*1c60b9acSAndroid Build Coastguard Worker #endif
454*1c60b9acSAndroid Build Coastguard Worker 						(mbedtls_md_type_t)h,
455*1c60b9acSAndroid Build Coastguard Worker 						(unsigned int)lws_genhash_size(hash_type),
456*1c60b9acSAndroid Build Coastguard Worker 						in, sig);
457*1c60b9acSAndroid Build Coastguard Worker 		break;
458*1c60b9acSAndroid Build Coastguard Worker 	default:
459*1c60b9acSAndroid Build Coastguard Worker 		return -1;
460*1c60b9acSAndroid Build Coastguard Worker 	}
461*1c60b9acSAndroid Build Coastguard Worker 
462*1c60b9acSAndroid Build Coastguard Worker 	if (n < 0) {
463*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: -0x%x\n", __func__, -n);
464*1c60b9acSAndroid Build Coastguard Worker 
465*1c60b9acSAndroid Build Coastguard Worker 		return -1;
466*1c60b9acSAndroid Build Coastguard Worker 	}
467*1c60b9acSAndroid Build Coastguard Worker 
468*1c60b9acSAndroid Build Coastguard Worker 	return (int)ctx->ctx->MBEDTLS_PRIVATE(len);
469*1c60b9acSAndroid Build Coastguard Worker }
470*1c60b9acSAndroid Build Coastguard Worker 
471*1c60b9acSAndroid Build Coastguard Worker int
472*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_render_pkey_asn1(struct lws_genrsa_ctx *ctx, int _private,
473*1c60b9acSAndroid Build Coastguard Worker 			    uint8_t *pkey_asn1, size_t pkey_asn1_len)
474*1c60b9acSAndroid Build Coastguard Worker {
475*1c60b9acSAndroid Build Coastguard Worker 	uint8_t *p = pkey_asn1, *totlen, *end = pkey_asn1 + pkey_asn1_len - 1;
476*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT] = {
477*1c60b9acSAndroid Build Coastguard Worker 		&ctx->ctx->MBEDTLS_PRIVATE(N),
478*1c60b9acSAndroid Build Coastguard Worker 		&ctx->ctx->MBEDTLS_PRIVATE(E),
479*1c60b9acSAndroid Build Coastguard Worker 		&ctx->ctx->MBEDTLS_PRIVATE(D),
480*1c60b9acSAndroid Build Coastguard Worker 		&ctx->ctx->MBEDTLS_PRIVATE(P),
481*1c60b9acSAndroid Build Coastguard Worker 		&ctx->ctx->MBEDTLS_PRIVATE(Q),
482*1c60b9acSAndroid Build Coastguard Worker 		&ctx->ctx->MBEDTLS_PRIVATE(DP),
483*1c60b9acSAndroid Build Coastguard Worker 		&ctx->ctx->MBEDTLS_PRIVATE(DQ),
484*1c60b9acSAndroid Build Coastguard Worker 		&ctx->ctx->MBEDTLS_PRIVATE(QP),
485*1c60b9acSAndroid Build Coastguard Worker 	};
486*1c60b9acSAndroid Build Coastguard Worker 	int n;
487*1c60b9acSAndroid Build Coastguard Worker 
488*1c60b9acSAndroid Build Coastguard Worker 	/* 30 82  - sequence
489*1c60b9acSAndroid Build Coastguard Worker 	 *   09 29  <-- length(0x0929) less 4 bytes
490*1c60b9acSAndroid Build Coastguard Worker 	 * 02 01 <- length (1)
491*1c60b9acSAndroid Build Coastguard Worker 	 *  00
492*1c60b9acSAndroid Build Coastguard Worker 	 * 02 82
493*1c60b9acSAndroid Build Coastguard Worker 	 *  02 01 <- length (513)  N
494*1c60b9acSAndroid Build Coastguard Worker 	 *  ...
495*1c60b9acSAndroid Build Coastguard Worker 	 *
496*1c60b9acSAndroid Build Coastguard Worker 	 *  02 03 <- length (3) E
497*1c60b9acSAndroid Build Coastguard Worker 	 *    01 00 01
498*1c60b9acSAndroid Build Coastguard Worker 	 *
499*1c60b9acSAndroid Build Coastguard Worker 	 * 02 82
500*1c60b9acSAndroid Build Coastguard Worker 	 *   02 00 <- length (512) D P Q EXP1 EXP2 COEFF
501*1c60b9acSAndroid Build Coastguard Worker 	 *
502*1c60b9acSAndroid Build Coastguard Worker 	 *  */
503*1c60b9acSAndroid Build Coastguard Worker 
504*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 0x30;
505*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 0x82;
506*1c60b9acSAndroid Build Coastguard Worker 	totlen = p;
507*1c60b9acSAndroid Build Coastguard Worker 	p += 2;
508*1c60b9acSAndroid Build Coastguard Worker 
509*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 0x02;
510*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 0x01;
511*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 0x00;
512*1c60b9acSAndroid Build Coastguard Worker 
513*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++) {
514*1c60b9acSAndroid Build Coastguard Worker 		int m = (int)mbedtls_mpi_size(mpi[n]);
515*1c60b9acSAndroid Build Coastguard Worker 		uint8_t *elen;
516*1c60b9acSAndroid Build Coastguard Worker 
517*1c60b9acSAndroid Build Coastguard Worker 		*p++ = 0x02;
518*1c60b9acSAndroid Build Coastguard Worker 		elen = p;
519*1c60b9acSAndroid Build Coastguard Worker 		if (m < 0x7f)
520*1c60b9acSAndroid Build Coastguard Worker 			*p++ = (uint8_t)m;
521*1c60b9acSAndroid Build Coastguard Worker 		else {
522*1c60b9acSAndroid Build Coastguard Worker 			*p++ = 0x82;
523*1c60b9acSAndroid Build Coastguard Worker 			*p++ = (uint8_t)(m >> 8);
524*1c60b9acSAndroid Build Coastguard Worker 			*p++ = (uint8_t)(m & 0xff);
525*1c60b9acSAndroid Build Coastguard Worker 		}
526*1c60b9acSAndroid Build Coastguard Worker 
527*1c60b9acSAndroid Build Coastguard Worker 		if (p + m > end)
528*1c60b9acSAndroid Build Coastguard Worker 			return -1;
529*1c60b9acSAndroid Build Coastguard Worker 
530*1c60b9acSAndroid Build Coastguard Worker 		if (mbedtls_mpi_write_binary(mpi[n], p, (unsigned int)m))
531*1c60b9acSAndroid Build Coastguard Worker 			return -1;
532*1c60b9acSAndroid Build Coastguard Worker 		if (p[0] & 0x80) {
533*1c60b9acSAndroid Build Coastguard Worker 			p[0] = 0x00;
534*1c60b9acSAndroid Build Coastguard Worker 			if (mbedtls_mpi_write_binary(mpi[n], &p[1], (unsigned int)m))
535*1c60b9acSAndroid Build Coastguard Worker 				return -1;
536*1c60b9acSAndroid Build Coastguard Worker 			m++;
537*1c60b9acSAndroid Build Coastguard Worker 		}
538*1c60b9acSAndroid Build Coastguard Worker 		if (m < 0x7f)
539*1c60b9acSAndroid Build Coastguard Worker 			*elen = (uint8_t)m;
540*1c60b9acSAndroid Build Coastguard Worker 		else {
541*1c60b9acSAndroid Build Coastguard Worker 			*elen++ = 0x82;
542*1c60b9acSAndroid Build Coastguard Worker 			*elen++ = (uint8_t)(m >> 8);
543*1c60b9acSAndroid Build Coastguard Worker 			*elen = (uint8_t)(m & 0xff);
544*1c60b9acSAndroid Build Coastguard Worker 		}
545*1c60b9acSAndroid Build Coastguard Worker 		p += m;
546*1c60b9acSAndroid Build Coastguard Worker 	}
547*1c60b9acSAndroid Build Coastguard Worker 
548*1c60b9acSAndroid Build Coastguard Worker 	n = lws_ptr_diff(p, pkey_asn1);
549*1c60b9acSAndroid Build Coastguard Worker 
550*1c60b9acSAndroid Build Coastguard Worker 	*totlen++ = (uint8_t)((n - 4) >> 8);
551*1c60b9acSAndroid Build Coastguard Worker 	*totlen = (uint8_t)((n - 4) & 0xff);
552*1c60b9acSAndroid Build Coastguard Worker 
553*1c60b9acSAndroid Build Coastguard Worker 	return n;
554*1c60b9acSAndroid Build Coastguard Worker }
555*1c60b9acSAndroid Build Coastguard Worker 
556*1c60b9acSAndroid Build Coastguard Worker void
557*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_destroy(struct lws_genrsa_ctx *ctx)
558*1c60b9acSAndroid Build Coastguard Worker {
559*1c60b9acSAndroid Build Coastguard Worker 	if (!ctx->ctx)
560*1c60b9acSAndroid Build Coastguard Worker 		return;
561*1c60b9acSAndroid Build Coastguard Worker 	mbedtls_rsa_free(ctx->ctx);
562*1c60b9acSAndroid Build Coastguard Worker 	lws_free(ctx->ctx);
563*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx = NULL;
564*1c60b9acSAndroid Build Coastguard Worker }
565