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