• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  *  lws_genrsa provides an RSA 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 void
lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem * el)36 lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem *el)
37 {
38 	lws_gencrypto_destroy_elements(el, LWS_GENCRYPTO_RSA_KEYEL_COUNT);
39 }
40 
41 static int mode_map_crypt[] = { RSA_PKCS1_PADDING, RSA_PKCS1_OAEP_PADDING },
42 	   mode_map_sig[]   = { RSA_PKCS1_PADDING, RSA_PKCS1_PSS_PADDING };
43 
44 static int
rsa_pkey_wrap(struct lws_genrsa_ctx * ctx,RSA * rsa)45 rsa_pkey_wrap(struct lws_genrsa_ctx *ctx, RSA *rsa)
46 {
47 	EVP_PKEY *pkey;
48 
49 	/* we have the RSA object filled up... wrap in a PKEY */
50 
51 	pkey = EVP_PKEY_new();
52 	if (!pkey)
53 		return 1;
54 
55 	/* bind the PKEY to the RSA key we just prepared */
56 
57 	if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
58 		lwsl_err("%s: EVP_PKEY_assign_RSA_KEY failed\n", __func__);
59 		goto bail;
60 	}
61 
62 	/* pepare our PKEY_CTX with the PKEY */
63 
64 	ctx->ctx = EVP_PKEY_CTX_new(pkey, NULL);
65 	EVP_PKEY_free(pkey);
66 	pkey = NULL;
67 	if (!ctx->ctx)
68 		goto bail;
69 
70 	return 0;
71 
72 bail:
73 	if (pkey)
74 		EVP_PKEY_free(pkey);
75 
76 	return 1;
77 }
78 
79 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)80 lws_genrsa_create(struct lws_genrsa_ctx *ctx,
81 		  const struct lws_gencrypto_keyelem *el,
82 		  struct lws_context *context, enum enum_genrsa_mode mode,
83 		  enum lws_genhash_types oaep_hashid)
84 {
85 	int n;
86 
87 	memset(ctx, 0, sizeof(*ctx));
88 	ctx->context = context;
89 	ctx->mode = mode;
90 
91 	/* Step 1:
92 	 *
93 	 * convert the MPI for e and n to OpenSSL BIGNUMs
94 	 */
95 
96 	for (n = 0; n < 5; n++) {
97 		ctx->bn[n] = BN_bin2bn(el[n].buf, (int)el[n].len, NULL);
98 		if (!ctx->bn[n]) {
99 			lwsl_notice("mpi load failed\n");
100 			goto bail;
101 		}
102 	}
103 
104 	/* Step 2:
105 	 *
106 	 * assemble the OpenSSL RSA from the BIGNUMs
107 	 */
108 
109 	ctx->rsa = RSA_new();
110 	if (!ctx->rsa) {
111 		lwsl_notice("Failed to create RSA\n");
112 		goto bail;
113 	}
114 
115 #if defined(LWS_HAVE_RSA_SET0_KEY) && !defined(USE_WOLFSSL)
116 	if (RSA_set0_key(ctx->rsa, ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_N],
117 			 ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_E],
118 			 ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_D]) != 1) {
119 		lwsl_notice("RSA_set0_key failed\n");
120 		goto bail;
121 	}
122 	RSA_set0_factors(ctx->rsa, ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_P],
123 				   ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_Q]);
124 #else
125 	ctx->rsa->e = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_E];
126 	ctx->rsa->n = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_N];
127 	ctx->rsa->d = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_D];
128 	ctx->rsa->p = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_P];
129 	ctx->rsa->q = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_Q];
130 #endif
131 
132 	if (!rsa_pkey_wrap(ctx, ctx->rsa))
133 		return 0;
134 
135 bail:
136 	for (n = 0; n < 5; n++)
137 		if (ctx->bn[n]) {
138 			BN_clear_free(ctx->bn[n]);
139 			ctx->bn[n] = NULL;
140 		}
141 
142 	if (ctx->rsa) {
143 		RSA_free(ctx->rsa);
144 		ctx->rsa = NULL;
145 	}
146 
147 	return 1;
148 }
149 
150 int
lws_genrsa_new_keypair(struct lws_context * context,struct lws_genrsa_ctx * ctx,enum enum_genrsa_mode mode,struct lws_gencrypto_keyelem * el,int bits)151 lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx *ctx,
152 		       enum enum_genrsa_mode mode, struct lws_gencrypto_keyelem *el,
153 		       int bits)
154 {
155 	BIGNUM *bn;
156 	int n;
157 
158 	memset(ctx, 0, sizeof(*ctx));
159 	ctx->context = context;
160 	ctx->mode = mode;
161 
162 	ctx->rsa = RSA_new();
163 	if (!ctx->rsa) {
164 		lwsl_notice("Failed to create RSA\n");
165 		return -1;
166 	}
167 
168 	bn = BN_new();
169 	if (!bn)
170 		goto cleanup_1;
171 	if (BN_set_word(bn, RSA_F4) != 1) {
172 		BN_free(bn);
173 		goto cleanup_1;
174 	}
175 
176 	n = RSA_generate_key_ex(ctx->rsa, bits, bn, NULL);
177 	BN_clear_free(bn);
178 	if (n != 1)
179 		goto cleanup_1;
180 
181 #if defined(LWS_HAVE_RSA_SET0_KEY) && !defined(USE_WOLFSSL)
182 	{
183 		const BIGNUM *mpi[5];
184 
185 		RSA_get0_key(ctx->rsa, &mpi[LWS_GENCRYPTO_RSA_KEYEL_N],
186 			     &mpi[LWS_GENCRYPTO_RSA_KEYEL_E], &mpi[LWS_GENCRYPTO_RSA_KEYEL_D]);
187 		RSA_get0_factors(ctx->rsa, &mpi[LWS_GENCRYPTO_RSA_KEYEL_P],
188 				 &mpi[LWS_GENCRYPTO_RSA_KEYEL_Q]);
189 #else
190 	{
191 		BIGNUM *mpi[5] = { ctx->rsa->e, ctx->rsa->n, ctx->rsa->d,
192 				   ctx->rsa->p, ctx->rsa->q, };
193 #endif
194 		for (n = 0; n < 5; n++)
195 			if (BN_num_bytes(mpi[n])) {
196 				el[n].buf = lws_malloc(
197 					(unsigned int)BN_num_bytes(mpi[n]), "genrsakey");
198 				if (!el[n].buf)
199 					goto cleanup;
200 				el[n].len = (unsigned int)BN_num_bytes(mpi[n]);
201 				BN_bn2bin(mpi[n], el[n].buf);
202 			}
203 	}
204 
205 	if (!rsa_pkey_wrap(ctx, ctx->rsa))
206 		return 0;
207 
208 cleanup:
209 	for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
210 		if (el[n].buf)
211 			lws_free_set_NULL(el[n].buf);
212 cleanup_1:
213 	RSA_free(ctx->rsa);
214 	ctx->rsa = NULL;
215 
216 	return -1;
217 }
218 
219 /*
220  * in_len must be less than RSA_size(rsa) - 11 for the PKCS #1 v1.5
221  * based padding modes
222  */
223 
224 int
225 lws_genrsa_public_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
226 			  size_t in_len, uint8_t *out)
227 {
228 	int n = RSA_public_encrypt((int)in_len, in, out, ctx->rsa,
229 				   mode_map_crypt[ctx->mode]);
230 	if (n < 0) {
231 		lwsl_err("%s: RSA_public_encrypt failed\n", __func__);
232 		lws_tls_err_describe_clear();
233 		return -1;
234 	}
235 
236 	return n;
237 }
238 
239 int
240 lws_genrsa_private_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
241 			   size_t in_len, uint8_t *out)
242 {
243 	int n = RSA_private_encrypt((int)in_len, in, out, ctx->rsa,
244 			        mode_map_crypt[ctx->mode]);
245 	if (n < 0) {
246 		lwsl_err("%s: RSA_private_encrypt failed\n", __func__);
247 		lws_tls_err_describe_clear();
248 		return -1;
249 	}
250 
251 	return n;
252 }
253 
254 int
255 lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
256 			  size_t in_len, uint8_t *out, size_t out_max)
257 {
258 	int n = RSA_public_decrypt((int)in_len, in, out, ctx->rsa,
259 			       mode_map_crypt[ctx->mode]);
260 	if (n < 0) {
261 		lwsl_err("%s: RSA_public_decrypt failed\n", __func__);
262 		return -1;
263 	}
264 
265 	return n;
266 }
267 
268 int
269 lws_genrsa_private_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
270 			   size_t in_len, uint8_t *out, size_t out_max)
271 {
272 	int n = RSA_private_decrypt((int)in_len, in, out, ctx->rsa,
273 			        mode_map_crypt[ctx->mode]);
274 	if (n < 0) {
275 		lwsl_err("%s: RSA_private_decrypt failed\n", __func__);
276 		lws_tls_err_describe_clear();
277 		return -1;
278 	}
279 
280 	return n;
281 }
282 
283 int
284 lws_genrsa_hash_sig_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in,
285 			 enum lws_genhash_types hash_type, const uint8_t *sig,
286 			 size_t sig_len)
287 {
288 	int n = lws_gencrypto_openssl_hash_to_NID(hash_type),
289 	    h = (int)lws_genhash_size(hash_type);
290 	const EVP_MD *md = NULL;
291 
292 	if (n < 0)
293 		return -1;
294 
295 	switch(ctx->mode) {
296 	case LGRSAM_PKCS1_1_5:
297 		n = RSA_verify(n, in, (unsigned int)h, (uint8_t *)sig,
298 			       (unsigned int)sig_len, ctx->rsa);
299 		break;
300 	case LGRSAM_PKCS1_OAEP_PSS:
301 		md = lws_gencrypto_openssl_hash_to_EVP_MD(hash_type);
302 		if (!md)
303 			return -1;
304 
305 #if defined(LWS_HAVE_RSA_verify_pss_mgf1)
306 		n = RSA_verify_pss_mgf1(ctx->rsa, in, h, md, NULL, -1,
307 					(uint8_t *)sig,
308 #else
309 		n = RSA_verify_PKCS1_PSS(ctx->rsa, in, md, (uint8_t *)sig,
310 #endif
311 					 (int)sig_len);
312 		break;
313 	default:
314 		return -1;
315 	}
316 
317 	if (n != 1) {
318 		lwsl_notice("%s: fail\n", __func__);
319 		lws_tls_err_describe_clear();
320 
321 		return -1;
322 	}
323 
324 	return 0;
325 }
326 
327 int
328 lws_genrsa_hash_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in,
329 		       enum lws_genhash_types hash_type, uint8_t *sig,
330 		       size_t sig_len)
331 {
332 	int n = lws_gencrypto_openssl_hash_to_NID(hash_type),
333 	    h = (int)lws_genhash_size(hash_type);
334 	unsigned int used = 0;
335 	EVP_MD_CTX *mdctx = NULL;
336 	const EVP_MD *md = NULL;
337 
338 	if (n < 0)
339 		return -1;
340 
341 	switch(ctx->mode) {
342 	case LGRSAM_PKCS1_1_5:
343 		if (RSA_sign(n, in, (unsigned int)h, sig, &used, ctx->rsa) != 1) {
344 			lwsl_err("%s: RSA_sign failed\n", __func__);
345 
346 			goto bail;
347 		}
348 		break;
349 
350 	case LGRSAM_PKCS1_OAEP_PSS:
351 
352 		md = lws_gencrypto_openssl_hash_to_EVP_MD(hash_type);
353 		if (!md)
354 			return -1;
355 
356 		if (EVP_PKEY_CTX_set_rsa_padding(ctx->ctx,
357 						 mode_map_sig[ctx->mode]) != 1) {
358 			lwsl_err("%s: set_rsa_padding failed\n", __func__);
359 
360 			goto bail;
361 		}
362 
363 		mdctx = EVP_MD_CTX_create();
364 		if (!mdctx)
365 			goto bail;
366 
367 		if (EVP_DigestSignInit(mdctx, NULL, md, NULL,
368 #if defined(USE_WOLFSSL)
369 					ctx->ctx->pkey)) {
370 #else
371 				       EVP_PKEY_CTX_get0_pkey(ctx->ctx))) {
372 #endif
373 			lwsl_err("%s: EVP_DigestSignInit failed\n", __func__);
374 
375 			goto bail;
376 		}
377 		if (EVP_DigestSignUpdate(mdctx, in, (unsigned int)EVP_MD_size(md))) {
378 			lwsl_err("%s: EVP_DigestSignUpdate failed\n", __func__);
379 
380 			goto bail;
381 		}
382 		if (EVP_DigestSignFinal(mdctx, sig, &sig_len)) {
383 			lwsl_err("%s: EVP_DigestSignFinal failed\n", __func__);
384 
385 			goto bail;
386 		}
387 		EVP_MD_CTX_free(mdctx);
388 		used = (unsigned int)sig_len;
389 		break;
390 
391 	default:
392 		return -1;
393 	}
394 
395 	return (int)used;
396 
397 bail:
398 	if (mdctx)
399 		EVP_MD_CTX_free(mdctx);
400 
401 	return -1;
402 }
403 
404 void
405 lws_genrsa_destroy(struct lws_genrsa_ctx *ctx)
406 {
407 	if (!ctx->ctx)
408 		return;
409 
410 	EVP_PKEY_CTX_free(ctx->ctx);
411 	ctx->ctx = NULL;
412 	ctx->rsa = NULL;
413 }
414