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,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, struct lws_gencrypto_keyelem *el,
81 struct lws_context *context, enum enum_genrsa_mode mode,
82 enum lws_genhash_types oaep_hashid)
83 {
84 int n;
85
86 memset(ctx, 0, sizeof(*ctx));
87 ctx->context = context;
88 ctx->mode = mode;
89
90 /* Step 1:
91 *
92 * convert the MPI for e and n to OpenSSL BIGNUMs
93 */
94
95 for (n = 0; n < 5; n++) {
96 ctx->bn[n] = BN_bin2bn(el[n].buf, el[n].len, NULL);
97 if (!ctx->bn[n]) {
98 lwsl_notice("mpi load failed\n");
99 goto bail;
100 }
101 }
102
103 /* Step 2:
104 *
105 * assemble the OpenSSL RSA from the BIGNUMs
106 */
107
108 ctx->rsa = RSA_new();
109 if (!ctx->rsa) {
110 lwsl_notice("Failed to create RSA\n");
111 goto bail;
112 }
113
114 #if defined(LWS_HAVE_RSA_SET0_KEY)
115 if (RSA_set0_key(ctx->rsa, ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_N],
116 ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_E],
117 ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_D]) != 1) {
118 lwsl_notice("RSA_set0_key failed\n");
119 goto bail;
120 }
121 RSA_set0_factors(ctx->rsa, ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_P],
122 ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_Q]);
123 #else
124 ctx->rsa->e = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_E];
125 ctx->rsa->n = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_N];
126 ctx->rsa->d = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_D];
127 ctx->rsa->p = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_P];
128 ctx->rsa->q = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_Q];
129 #endif
130
131 if (!rsa_pkey_wrap(ctx, ctx->rsa))
132 return 0;
133
134 bail:
135 for (n = 0; n < 5; n++)
136 if (ctx->bn[n]) {
137 BN_clear_free(ctx->bn[n]);
138 ctx->bn[n] = NULL;
139 }
140
141 if (ctx->rsa) {
142 RSA_free(ctx->rsa);
143 ctx->rsa = NULL;
144 }
145
146 return 1;
147 }
148
149 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)150 lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx *ctx,
151 enum enum_genrsa_mode mode, struct lws_gencrypto_keyelem *el,
152 int bits)
153 {
154 BIGNUM *bn;
155 int n;
156
157 memset(ctx, 0, sizeof(*ctx));
158 ctx->context = context;
159 ctx->mode = mode;
160
161 ctx->rsa = RSA_new();
162 if (!ctx->rsa) {
163 lwsl_notice("Failed to create RSA\n");
164 return -1;
165 }
166
167 bn = BN_new();
168 if (!bn)
169 goto cleanup_1;
170 if (BN_set_word(bn, RSA_F4) != 1) {
171 BN_free(bn);
172 goto cleanup_1;
173 }
174
175 n = RSA_generate_key_ex(ctx->rsa, bits, bn, NULL);
176 BN_clear_free(bn);
177 if (n != 1)
178 goto cleanup_1;
179
180 #if defined(LWS_HAVE_RSA_SET0_KEY)
181 {
182 const BIGNUM *mpi[5];
183
184 RSA_get0_key(ctx->rsa, &mpi[LWS_GENCRYPTO_RSA_KEYEL_N],
185 &mpi[LWS_GENCRYPTO_RSA_KEYEL_E], &mpi[LWS_GENCRYPTO_RSA_KEYEL_D]);
186 RSA_get0_factors(ctx->rsa, &mpi[LWS_GENCRYPTO_RSA_KEYEL_P],
187 &mpi[LWS_GENCRYPTO_RSA_KEYEL_Q]);
188 #else
189 {
190 BIGNUM *mpi[5] = { ctx->rsa->e, ctx->rsa->n, ctx->rsa->d,
191 ctx->rsa->p, ctx->rsa->q, };
192 #endif
193 for (n = 0; n < 5; n++)
194 if (BN_num_bytes(mpi[n])) {
195 el[n].buf = lws_malloc(
196 BN_num_bytes(mpi[n]), "genrsakey");
197 if (!el[n].buf)
198 goto cleanup;
199 el[n].len = BN_num_bytes(mpi[n]);
200 BN_bn2bin(mpi[n], el[n].buf);
201 }
202 }
203
204 if (!rsa_pkey_wrap(ctx, ctx->rsa))
205 return 0;
206
207 cleanup:
208 for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
209 if (el[n].buf)
210 lws_free_set_NULL(el[n].buf);
211 cleanup_1:
212 RSA_free(ctx->rsa);
213 ctx->rsa = NULL;
214
215 return -1;
216 }
217
218 /*
219 * in_len must be less than RSA_size(rsa) - 11 for the PKCS #1 v1.5
220 * based padding modes
221 */
222
223 int
224 lws_genrsa_public_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
225 size_t in_len, uint8_t *out)
226 {
227 int n = RSA_public_encrypt((int)in_len, in, out, ctx->rsa,
228 mode_map_crypt[ctx->mode]);
229 if (n < 0) {
230 lwsl_err("%s: RSA_public_encrypt failed\n", __func__);
231 lws_tls_err_describe_clear();
232 return -1;
233 }
234
235 return n;
236 }
237
238 int
239 lws_genrsa_private_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
240 size_t in_len, uint8_t *out)
241 {
242 int n = RSA_private_encrypt((int)in_len, in, out, ctx->rsa,
243 mode_map_crypt[ctx->mode]);
244 if (n < 0) {
245 lwsl_err("%s: RSA_private_encrypt failed\n", __func__);
246 lws_tls_err_describe_clear();
247 return -1;
248 }
249
250 return n;
251 }
252
253 int
254 lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
255 size_t in_len, uint8_t *out, size_t out_max)
256 {
257 int n = RSA_public_decrypt((int)in_len, in, out, ctx->rsa,
258 mode_map_crypt[ctx->mode]);
259 if (n < 0) {
260 lwsl_err("%s: RSA_public_decrypt failed\n", __func__);
261 return -1;
262 }
263
264 return n;
265 }
266
267 int
268 lws_genrsa_private_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
269 size_t in_len, uint8_t *out, size_t out_max)
270 {
271 int n = RSA_private_decrypt((int)in_len, in, out, ctx->rsa,
272 mode_map_crypt[ctx->mode]);
273 if (n < 0) {
274 lwsl_err("%s: RSA_private_decrypt failed\n", __func__);
275 lws_tls_err_describe_clear();
276 return -1;
277 }
278
279 return n;
280 }
281
282 int
283 lws_genrsa_hash_sig_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in,
284 enum lws_genhash_types hash_type, const uint8_t *sig,
285 size_t sig_len)
286 {
287 int n = lws_gencrypto_openssl_hash_to_NID(hash_type),
288 h = (int)lws_genhash_size(hash_type);
289 const EVP_MD *md = NULL;
290
291 if (n < 0)
292 return -1;
293
294 switch(ctx->mode) {
295 case LGRSAM_PKCS1_1_5:
296 n = RSA_verify(n, in, h, (uint8_t *)sig, (int)sig_len, ctx->rsa);
297 break;
298 case LGRSAM_PKCS1_OAEP_PSS:
299 md = lws_gencrypto_openssl_hash_to_EVP_MD(hash_type);
300 if (!md)
301 return -1;
302
303 #if defined(LWS_HAVE_RSA_verify_pss_mgf1)
304 n = RSA_verify_pss_mgf1(ctx->rsa, in, h, md, NULL, -1,
305 (uint8_t *)sig,
306 #else
307 n = RSA_verify_PKCS1_PSS(ctx->rsa, in, md, (uint8_t *)sig,
308 #endif
309 (int)sig_len);
310 break;
311 default:
312 return -1;
313 }
314
315 if (n != 1) {
316 lwsl_notice("%s: fail\n", __func__);
317 lws_tls_err_describe_clear();
318
319 return -1;
320 }
321
322 return 0;
323 }
324
325 int
326 lws_genrsa_hash_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in,
327 enum lws_genhash_types hash_type, uint8_t *sig,
328 size_t sig_len)
329 {
330 int n = lws_gencrypto_openssl_hash_to_NID(hash_type),
331 h = (int)lws_genhash_size(hash_type);
332 unsigned int used = 0;
333 EVP_MD_CTX *mdctx = NULL;
334 const EVP_MD *md = NULL;
335
336 if (n < 0)
337 return -1;
338
339 switch(ctx->mode) {
340 case LGRSAM_PKCS1_1_5:
341 if (RSA_sign(n, in, h, sig, &used, ctx->rsa) != 1) {
342 lwsl_err("%s: RSA_sign failed\n", __func__);
343
344 goto bail;
345 }
346 break;
347
348 case LGRSAM_PKCS1_OAEP_PSS:
349
350 md = lws_gencrypto_openssl_hash_to_EVP_MD(hash_type);
351 if (!md)
352 return -1;
353
354 if (EVP_PKEY_CTX_set_rsa_padding(ctx->ctx,
355 mode_map_sig[ctx->mode]) != 1) {
356 lwsl_err("%s: set_rsa_padding failed\n", __func__);
357
358 goto bail;
359 }
360
361 mdctx = EVP_MD_CTX_create();
362 if (!mdctx)
363 goto bail;
364
365 if (EVP_DigestSignInit(mdctx, NULL, md, NULL,
366 EVP_PKEY_CTX_get0_pkey(ctx->ctx))) {
367 lwsl_err("%s: EVP_DigestSignInit failed\n", __func__);
368
369 goto bail;
370 }
371 if (EVP_DigestSignUpdate(mdctx, in, EVP_MD_size(md))) {
372 lwsl_err("%s: EVP_DigestSignUpdate failed\n", __func__);
373
374 goto bail;
375 }
376 if (EVP_DigestSignFinal(mdctx, sig, &sig_len)) {
377 lwsl_err("%s: EVP_DigestSignFinal failed\n", __func__);
378
379 goto bail;
380 }
381 EVP_MD_CTX_free(mdctx);
382 used = (int)sig_len;
383 break;
384
385 default:
386 return -1;
387 }
388
389 return used;
390
391 bail:
392 if (mdctx)
393 EVP_MD_CTX_free(mdctx);
394
395 return -1;
396 }
397
398 void
399 lws_genrsa_destroy(struct lws_genrsa_ctx *ctx)
400 {
401 if (!ctx->ctx)
402 return;
403
404 EVP_PKEY_CTX_free(ctx->ctx);
405 ctx->ctx = NULL;
406 ctx->rsa = NULL;
407 }
408