lws-genrsa.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  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. * Care: many openssl apis return 1 for success. These are translated to the
  31. * lws convention of 0 for success.
  32. */
  33. void
  34. lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem *el)
  35. {
  36. lws_gencrypto_destroy_elements(el, LWS_GENCRYPTO_RSA_KEYEL_COUNT);
  37. }
  38. static int mode_map_crypt[] = { RSA_PKCS1_PADDING, RSA_PKCS1_OAEP_PADDING },
  39. mode_map_sig[] = { RSA_PKCS1_PADDING, RSA_PKCS1_PSS_PADDING };
  40. static int
  41. rsa_pkey_wrap(struct lws_genrsa_ctx *ctx, RSA *rsa)
  42. {
  43. EVP_PKEY *pkey;
  44. /* we have the RSA object filled up... wrap in a PKEY */
  45. pkey = EVP_PKEY_new();
  46. if (!pkey)
  47. return 1;
  48. /* bind the PKEY to the RSA key we just prepared */
  49. if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
  50. lwsl_err("%s: EVP_PKEY_assign_RSA_KEY failed\n", __func__);
  51. goto bail;
  52. }
  53. /* pepare our PKEY_CTX with the PKEY */
  54. ctx->ctx = EVP_PKEY_CTX_new(pkey, NULL);
  55. EVP_PKEY_free(pkey);
  56. pkey = NULL;
  57. if (!ctx->ctx)
  58. goto bail;
  59. return 0;
  60. bail:
  61. if (pkey)
  62. EVP_PKEY_free(pkey);
  63. return 1;
  64. }
  65. int
  66. lws_genrsa_create(struct lws_genrsa_ctx *ctx, struct lws_gencrypto_keyelem *el,
  67. struct lws_context *context, enum enum_genrsa_mode mode,
  68. enum lws_genhash_types oaep_hashid)
  69. {
  70. int n;
  71. memset(ctx, 0, sizeof(*ctx));
  72. ctx->context = context;
  73. ctx->mode = mode;
  74. /* Step 1:
  75. *
  76. * convert the MPI for e and n to OpenSSL BIGNUMs
  77. */
  78. for (n = 0; n < 5; n++) {
  79. ctx->bn[n] = BN_bin2bn(el[n].buf, el[n].len, NULL);
  80. if (!ctx->bn[n]) {
  81. lwsl_notice("mpi load failed\n");
  82. goto bail;
  83. }
  84. }
  85. /* Step 2:
  86. *
  87. * assemble the OpenSSL RSA from the BIGNUMs
  88. */
  89. ctx->rsa = RSA_new();
  90. if (!ctx->rsa) {
  91. lwsl_notice("Failed to create RSA\n");
  92. goto bail;
  93. }
  94. #if defined(LWS_HAVE_RSA_SET0_KEY)
  95. if (RSA_set0_key(ctx->rsa, ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_N],
  96. ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_E],
  97. ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_D]) != 1) {
  98. lwsl_notice("RSA_set0_key failed\n");
  99. goto bail;
  100. }
  101. RSA_set0_factors(ctx->rsa, ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_P],
  102. ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_Q]);
  103. #else
  104. ctx->rsa->e = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_E];
  105. ctx->rsa->n = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_N];
  106. ctx->rsa->d = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_D];
  107. ctx->rsa->p = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_P];
  108. ctx->rsa->q = ctx->bn[LWS_GENCRYPTO_RSA_KEYEL_Q];
  109. #endif
  110. if (!rsa_pkey_wrap(ctx, ctx->rsa))
  111. return 0;
  112. bail:
  113. for (n = 0; n < 5; n++)
  114. if (ctx->bn[n]) {
  115. BN_clear_free(ctx->bn[n]);
  116. ctx->bn[n] = NULL;
  117. }
  118. if (ctx->rsa) {
  119. RSA_free(ctx->rsa);
  120. ctx->rsa = NULL;
  121. }
  122. return 1;
  123. }
  124. int
  125. lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx *ctx,
  126. enum enum_genrsa_mode mode, struct lws_gencrypto_keyelem *el,
  127. int bits)
  128. {
  129. BIGNUM *bn;
  130. int n;
  131. memset(ctx, 0, sizeof(*ctx));
  132. ctx->context = context;
  133. ctx->mode = mode;
  134. ctx->rsa = RSA_new();
  135. if (!ctx->rsa) {
  136. lwsl_notice("Failed to create RSA\n");
  137. return -1;
  138. }
  139. bn = BN_new();
  140. if (!bn)
  141. goto cleanup_1;
  142. if (BN_set_word(bn, RSA_F4) != 1) {
  143. BN_free(bn);
  144. goto cleanup_1;
  145. }
  146. n = RSA_generate_key_ex(ctx->rsa, bits, bn, NULL);
  147. BN_clear_free(bn);
  148. if (n != 1)
  149. goto cleanup_1;
  150. #if defined(LWS_HAVE_RSA_SET0_KEY)
  151. {
  152. const BIGNUM *mpi[5];
  153. RSA_get0_key(ctx->rsa, &mpi[LWS_GENCRYPTO_RSA_KEYEL_N],
  154. &mpi[LWS_GENCRYPTO_RSA_KEYEL_E], &mpi[LWS_GENCRYPTO_RSA_KEYEL_D]);
  155. RSA_get0_factors(ctx->rsa, &mpi[LWS_GENCRYPTO_RSA_KEYEL_P],
  156. &mpi[LWS_GENCRYPTO_RSA_KEYEL_Q]);
  157. #else
  158. {
  159. BIGNUM *mpi[5] = { ctx->rsa->e, ctx->rsa->n, ctx->rsa->d,
  160. ctx->rsa->p, ctx->rsa->q, };
  161. #endif
  162. for (n = 0; n < 5; n++)
  163. if (BN_num_bytes(mpi[n])) {
  164. el[n].buf = lws_malloc(
  165. BN_num_bytes(mpi[n]), "genrsakey");
  166. if (!el[n].buf)
  167. goto cleanup;
  168. el[n].len = BN_num_bytes(mpi[n]);
  169. BN_bn2bin(mpi[n], el[n].buf);
  170. }
  171. }
  172. if (!rsa_pkey_wrap(ctx, ctx->rsa))
  173. return 0;
  174. cleanup:
  175. for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
  176. if (el[n].buf)
  177. lws_free_set_NULL(el[n].buf);
  178. cleanup_1:
  179. RSA_free(ctx->rsa);
  180. ctx->rsa = NULL;
  181. return -1;
  182. }
  183. /*
  184. * in_len must be less than RSA_size(rsa) - 11 for the PKCS #1 v1.5
  185. * based padding modes
  186. */
  187. int
  188. lws_genrsa_public_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  189. size_t in_len, uint8_t *out)
  190. {
  191. int n = RSA_public_encrypt((int)in_len, in, out, ctx->rsa,
  192. mode_map_crypt[ctx->mode]);
  193. if (n < 0) {
  194. lwsl_err("%s: RSA_public_encrypt failed\n", __func__);
  195. lws_tls_err_describe_clear();
  196. return -1;
  197. }
  198. return n;
  199. }
  200. int
  201. lws_genrsa_private_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  202. size_t in_len, uint8_t *out)
  203. {
  204. int n = RSA_private_encrypt((int)in_len, in, out, ctx->rsa,
  205. mode_map_crypt[ctx->mode]);
  206. if (n < 0) {
  207. lwsl_err("%s: RSA_private_encrypt failed\n", __func__);
  208. lws_tls_err_describe_clear();
  209. return -1;
  210. }
  211. return n;
  212. }
  213. int
  214. lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  215. size_t in_len, uint8_t *out, size_t out_max)
  216. {
  217. int n = RSA_public_decrypt((int)in_len, in, out, ctx->rsa,
  218. mode_map_crypt[ctx->mode]);
  219. if (n < 0) {
  220. lwsl_err("%s: RSA_public_decrypt failed\n", __func__);
  221. return -1;
  222. }
  223. return n;
  224. }
  225. int
  226. lws_genrsa_private_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  227. size_t in_len, uint8_t *out, size_t out_max)
  228. {
  229. int n = RSA_private_decrypt((int)in_len, in, out, ctx->rsa,
  230. mode_map_crypt[ctx->mode]);
  231. if (n < 0) {
  232. lwsl_err("%s: RSA_private_decrypt failed\n", __func__);
  233. lws_tls_err_describe_clear();
  234. return -1;
  235. }
  236. return n;
  237. }
  238. int
  239. lws_genrsa_hash_sig_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  240. enum lws_genhash_types hash_type, const uint8_t *sig,
  241. size_t sig_len)
  242. {
  243. int n = lws_gencrypto_openssl_hash_to_NID(hash_type),
  244. h = (int)lws_genhash_size(hash_type);
  245. const EVP_MD *md = NULL;
  246. if (n < 0)
  247. return -1;
  248. switch(ctx->mode) {
  249. case LGRSAM_PKCS1_1_5:
  250. n = RSA_verify(n, in, h, (uint8_t *)sig, (int)sig_len, ctx->rsa);
  251. break;
  252. case LGRSAM_PKCS1_OAEP_PSS:
  253. md = lws_gencrypto_openssl_hash_to_EVP_MD(hash_type);
  254. if (!md)
  255. return -1;
  256. #if defined(LWS_HAVE_RSA_verify_pss_mgf1)
  257. n = RSA_verify_pss_mgf1(ctx->rsa, in, h, md, NULL, -1,
  258. (uint8_t *)sig,
  259. #else
  260. n = RSA_verify_PKCS1_PSS(ctx->rsa, in, md, (uint8_t *)sig,
  261. #endif
  262. (int)sig_len);
  263. break;
  264. default:
  265. return -1;
  266. }
  267. if (n != 1) {
  268. lwsl_notice("%s: fail\n", __func__);
  269. lws_tls_err_describe_clear();
  270. return -1;
  271. }
  272. return 0;
  273. }
  274. int
  275. lws_genrsa_hash_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  276. enum lws_genhash_types hash_type, uint8_t *sig,
  277. size_t sig_len)
  278. {
  279. int n = lws_gencrypto_openssl_hash_to_NID(hash_type),
  280. h = (int)lws_genhash_size(hash_type);
  281. unsigned int used = 0;
  282. EVP_MD_CTX *mdctx = NULL;
  283. const EVP_MD *md = NULL;
  284. if (n < 0)
  285. return -1;
  286. switch(ctx->mode) {
  287. case LGRSAM_PKCS1_1_5:
  288. if (RSA_sign(n, in, h, sig, &used, ctx->rsa) != 1) {
  289. lwsl_err("%s: RSA_sign failed\n", __func__);
  290. goto bail;
  291. }
  292. break;
  293. case LGRSAM_PKCS1_OAEP_PSS:
  294. md = lws_gencrypto_openssl_hash_to_EVP_MD(hash_type);
  295. if (!md)
  296. return -1;
  297. if (EVP_PKEY_CTX_set_rsa_padding(ctx->ctx,
  298. mode_map_sig[ctx->mode]) != 1) {
  299. lwsl_err("%s: set_rsa_padding failed\n", __func__);
  300. goto bail;
  301. }
  302. mdctx = EVP_MD_CTX_create();
  303. if (!mdctx)
  304. goto bail;
  305. if (EVP_DigestSignInit(mdctx, NULL, md, NULL,
  306. EVP_PKEY_CTX_get0_pkey(ctx->ctx))) {
  307. lwsl_err("%s: EVP_DigestSignInit failed\n", __func__);
  308. goto bail;
  309. }
  310. if (EVP_DigestSignUpdate(mdctx, in, EVP_MD_size(md))) {
  311. lwsl_err("%s: EVP_DigestSignUpdate failed\n", __func__);
  312. goto bail;
  313. }
  314. if (EVP_DigestSignFinal(mdctx, sig, &sig_len)) {
  315. lwsl_err("%s: EVP_DigestSignFinal failed\n", __func__);
  316. goto bail;
  317. }
  318. EVP_MD_CTX_free(mdctx);
  319. used = (int)sig_len;
  320. break;
  321. default:
  322. return -1;
  323. }
  324. return used;
  325. bail:
  326. if (mdctx)
  327. EVP_MD_CTX_free(mdctx);
  328. return -1;
  329. }
  330. void
  331. lws_genrsa_destroy(struct lws_genrsa_ctx *ctx)
  332. {
  333. if (!ctx->ctx)
  334. return;
  335. EVP_PKEY_CTX_free(ctx->ctx);
  336. ctx->ctx = NULL;
  337. ctx->rsa = NULL;
  338. }