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