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