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
35void
36lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem *el)
37{
38	lws_gencrypto_destroy_elements(el, LWS_GENCRYPTO_RSA_KEYEL_COUNT);
39}
40
41static int mode_map_crypt[] = { RSA_PKCS1_PADDING, RSA_PKCS1_OAEP_PADDING },
42	   mode_map_sig[]   = { RSA_PKCS1_PADDING, RSA_PKCS1_PSS_PADDING };
43
44static int
45rsa_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
72bail:
73	if (pkey)
74		EVP_PKEY_free(pkey);
75
76	return 1;
77}
78
79int
80lws_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
135bail:
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
150int
151lws_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
208cleanup:
209	for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
210		if (el[n].buf)
211			lws_free_set_NULL(el[n].buf);
212cleanup_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
224int
225lws_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
239int
240lws_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
254int
255lws_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
268int
269lws_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
283int
284lws_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
327int
328lws_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
397bail:
398	if (mdctx)
399		EVP_MD_CTX_free(mdctx);
400
401	return -1;
402}
403
404void
405lws_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