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