lws-genrsa.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  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-mbedtls.h"
  29. #include <mbedtls/rsa.h>
  30. void
  31. lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem *el)
  32. {
  33. int n;
  34. for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
  35. if (el[n].buf)
  36. lws_free_set_NULL(el[n].buf);
  37. }
  38. static int mode_map[] = { MBEDTLS_RSA_PKCS_V15, MBEDTLS_RSA_PKCS_V21 };
  39. int
  40. lws_genrsa_create(struct lws_genrsa_ctx *ctx, struct lws_gencrypto_keyelem *el,
  41. struct lws_context *context, enum enum_genrsa_mode mode,
  42. enum lws_genhash_types oaep_hashid)
  43. {
  44. memset(ctx, 0, sizeof(*ctx));
  45. ctx->ctx = lws_zalloc(sizeof(*ctx->ctx), "genrsa");
  46. if (!ctx->ctx)
  47. return 1;
  48. ctx->context = context;
  49. ctx->mode = mode;
  50. if (mode >= LGRSAM_COUNT)
  51. return -1;
  52. mbedtls_rsa_init(ctx->ctx, mode_map[mode], 0);
  53. ctx->ctx->padding = mode_map[mode];
  54. ctx->ctx->hash_id = lws_gencrypto_mbedtls_hash_to_MD_TYPE(oaep_hashid);
  55. {
  56. int n;
  57. mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT] = {
  58. &ctx->ctx->E, &ctx->ctx->N, &ctx->ctx->D, &ctx->ctx->P,
  59. &ctx->ctx->Q, &ctx->ctx->DP, &ctx->ctx->DQ,
  60. &ctx->ctx->QP,
  61. };
  62. for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
  63. if (el[n].buf &&
  64. mbedtls_mpi_read_binary(mpi[n], el[n].buf,
  65. el[n].len)) {
  66. lwsl_notice("mpi load failed\n");
  67. lws_free_set_NULL(ctx->ctx);
  68. return -1;
  69. }
  70. /* mbedtls... compute missing P & Q */
  71. if ( el[LWS_GENCRYPTO_RSA_KEYEL_D].len &&
  72. !el[LWS_GENCRYPTO_RSA_KEYEL_P].len &&
  73. !el[LWS_GENCRYPTO_RSA_KEYEL_Q].len) {
  74. #if defined(LWS_HAVE_mbedtls_rsa_complete)
  75. if (mbedtls_rsa_complete(ctx->ctx)) {
  76. lwsl_notice("mbedtls_rsa_complete failed\n");
  77. #else
  78. {
  79. lwsl_notice("%s: you have to provide P and Q\n", __func__);
  80. #endif
  81. lws_free_set_NULL(ctx->ctx);
  82. return -1;
  83. }
  84. }
  85. }
  86. ctx->ctx->len = el[LWS_GENCRYPTO_RSA_KEYEL_N].len;
  87. return 0;
  88. }
  89. static int
  90. _rngf(void *context, unsigned char *buf, size_t len)
  91. {
  92. if ((size_t)lws_get_random(context, buf, len) == len)
  93. return 0;
  94. return -1;
  95. }
  96. int
  97. lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx *ctx,
  98. enum enum_genrsa_mode mode, struct lws_gencrypto_keyelem *el,
  99. int bits)
  100. {
  101. int n;
  102. memset(ctx, 0, sizeof(*ctx));
  103. ctx->ctx = lws_zalloc(sizeof(*ctx->ctx), "genrsa");
  104. if (!ctx->ctx)
  105. return -1;
  106. ctx->context = context;
  107. ctx->mode = mode;
  108. if (mode >= LGRSAM_COUNT)
  109. return -1;
  110. mbedtls_rsa_init(ctx->ctx, mode_map[mode], 0);
  111. n = mbedtls_rsa_gen_key(ctx->ctx, _rngf, context, bits, 65537);
  112. if (n) {
  113. lwsl_err("mbedtls_rsa_gen_key failed 0x%x\n", -n);
  114. goto cleanup_1;
  115. }
  116. {
  117. mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT] = {
  118. &ctx->ctx->E, &ctx->ctx->N, &ctx->ctx->D, &ctx->ctx->P,
  119. &ctx->ctx->Q, &ctx->ctx->DP, &ctx->ctx->DQ,
  120. &ctx->ctx->QP,
  121. };
  122. for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
  123. if (mbedtls_mpi_size(mpi[n])) {
  124. el[n].buf = lws_malloc(
  125. mbedtls_mpi_size(mpi[n]), "genrsakey");
  126. if (!el[n].buf)
  127. goto cleanup;
  128. el[n].len = mbedtls_mpi_size(mpi[n]);
  129. if (mbedtls_mpi_write_binary(mpi[n], el[n].buf,
  130. el[n].len))
  131. goto cleanup;
  132. }
  133. }
  134. return 0;
  135. cleanup:
  136. for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++)
  137. if (el[n].buf)
  138. lws_free_set_NULL(el[n].buf);
  139. cleanup_1:
  140. lws_free(ctx->ctx);
  141. return -1;
  142. }
  143. int
  144. lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  145. size_t in_len, uint8_t *out, size_t out_max)
  146. {
  147. size_t olen = 0;
  148. int n;
  149. ctx->ctx->len = in_len;
  150. #if defined(LWS_HAVE_mbedtls_rsa_complete)
  151. mbedtls_rsa_complete(ctx->ctx);
  152. #endif
  153. switch(ctx->mode) {
  154. case LGRSAM_PKCS1_1_5:
  155. n = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(ctx->ctx, _rngf,
  156. ctx->context,
  157. MBEDTLS_RSA_PUBLIC,
  158. &olen, in, out,
  159. out_max);
  160. break;
  161. case LGRSAM_PKCS1_OAEP_PSS:
  162. n = mbedtls_rsa_rsaes_oaep_decrypt(ctx->ctx, _rngf,
  163. ctx->context,
  164. MBEDTLS_RSA_PUBLIC,
  165. NULL, 0,
  166. &olen, in, out, out_max);
  167. break;
  168. default:
  169. return -1;
  170. }
  171. if (n) {
  172. lwsl_notice("%s: -0x%x\n", __func__, -n);
  173. return -1;
  174. }
  175. return olen;
  176. }
  177. int
  178. lws_genrsa_private_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  179. size_t in_len, uint8_t *out, size_t out_max)
  180. {
  181. size_t olen = 0;
  182. int n;
  183. ctx->ctx->len = in_len;
  184. #if defined(LWS_HAVE_mbedtls_rsa_complete)
  185. mbedtls_rsa_complete(ctx->ctx);
  186. #endif
  187. switch(ctx->mode) {
  188. case LGRSAM_PKCS1_1_5:
  189. n = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(ctx->ctx, _rngf,
  190. ctx->context,
  191. MBEDTLS_RSA_PRIVATE,
  192. &olen, in, out,
  193. out_max);
  194. break;
  195. case LGRSAM_PKCS1_OAEP_PSS:
  196. n = mbedtls_rsa_rsaes_oaep_decrypt(ctx->ctx, _rngf,
  197. ctx->context,
  198. MBEDTLS_RSA_PRIVATE,
  199. NULL, 0,
  200. &olen, in, out, out_max);
  201. break;
  202. default:
  203. return -1;
  204. }
  205. if (n) {
  206. lwsl_notice("%s: -0x%x\n", __func__, -n);
  207. return -1;
  208. }
  209. return olen;
  210. }
  211. int
  212. lws_genrsa_public_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  213. size_t in_len, uint8_t *out)
  214. {
  215. int n;
  216. #if defined(LWS_HAVE_mbedtls_rsa_complete)
  217. mbedtls_rsa_complete(ctx->ctx);
  218. #endif
  219. switch(ctx->mode) {
  220. case LGRSAM_PKCS1_1_5:
  221. n = mbedtls_rsa_rsaes_pkcs1_v15_encrypt(ctx->ctx, _rngf,
  222. ctx->context,
  223. MBEDTLS_RSA_PUBLIC,
  224. in_len, in, out);
  225. break;
  226. case LGRSAM_PKCS1_OAEP_PSS:
  227. n = mbedtls_rsa_rsaes_oaep_encrypt(ctx->ctx, _rngf,
  228. ctx->context,
  229. MBEDTLS_RSA_PUBLIC,
  230. NULL, 0,
  231. in_len, in, out);
  232. break;
  233. default:
  234. return -1;
  235. }
  236. if (n < 0) {
  237. lwsl_notice("%s: -0x%x: in_len: %d\n", __func__, -n,
  238. (int)in_len);
  239. return -1;
  240. }
  241. return mbedtls_mpi_size(&ctx->ctx->N);
  242. }
  243. int
  244. lws_genrsa_private_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  245. size_t in_len, uint8_t *out)
  246. {
  247. int n;
  248. #if defined(LWS_HAVE_mbedtls_rsa_complete)
  249. mbedtls_rsa_complete(ctx->ctx);
  250. #endif
  251. switch(ctx->mode) {
  252. case LGRSAM_PKCS1_1_5:
  253. n = mbedtls_rsa_rsaes_pkcs1_v15_encrypt(ctx->ctx, _rngf,
  254. ctx->context,
  255. MBEDTLS_RSA_PRIVATE,
  256. in_len, in, out);
  257. break;
  258. case LGRSAM_PKCS1_OAEP_PSS:
  259. n = mbedtls_rsa_rsaes_oaep_encrypt(ctx->ctx, _rngf,
  260. ctx->context,
  261. MBEDTLS_RSA_PRIVATE,
  262. NULL, 0,
  263. in_len, in, out);
  264. break;
  265. default:
  266. return -1;
  267. }
  268. if (n) {
  269. lwsl_notice("%s: -0x%x: in_len: %d\n", __func__, -n,
  270. (int)in_len);
  271. return -1;
  272. }
  273. return mbedtls_mpi_size(&ctx->ctx->N);
  274. }
  275. int
  276. lws_genrsa_hash_sig_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  277. enum lws_genhash_types hash_type, const uint8_t *sig,
  278. size_t sig_len)
  279. {
  280. int n, h = lws_gencrypto_mbedtls_hash_to_MD_TYPE(hash_type);
  281. if (h < 0)
  282. return -1;
  283. #if defined(LWS_HAVE_mbedtls_rsa_complete)
  284. mbedtls_rsa_complete(ctx->ctx);
  285. #endif
  286. switch(ctx->mode) {
  287. case LGRSAM_PKCS1_1_5:
  288. n = mbedtls_rsa_rsassa_pkcs1_v15_verify(ctx->ctx, NULL, NULL,
  289. MBEDTLS_RSA_PUBLIC,
  290. h, 0, in, sig);
  291. break;
  292. case LGRSAM_PKCS1_OAEP_PSS:
  293. n = mbedtls_rsa_rsassa_pss_verify(ctx->ctx, NULL, NULL,
  294. MBEDTLS_RSA_PUBLIC,
  295. h, 0, in, sig);
  296. break;
  297. default:
  298. return -1;
  299. }
  300. if (n < 0) {
  301. lwsl_notice("%s: -0x%x\n", __func__, -n);
  302. return -1;
  303. }
  304. return n;
  305. }
  306. int
  307. lws_genrsa_hash_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  308. enum lws_genhash_types hash_type, uint8_t *sig,
  309. size_t sig_len)
  310. {
  311. int n, h = lws_gencrypto_mbedtls_hash_to_MD_TYPE(hash_type);
  312. if (h < 0)
  313. return -1;
  314. #if defined(LWS_HAVE_mbedtls_rsa_complete)
  315. mbedtls_rsa_complete(ctx->ctx);
  316. #endif
  317. /*
  318. * The "sig" buffer must be as large as the size of ctx->N
  319. * (eg. 128 bytes if RSA-1024 is used).
  320. */
  321. if (sig_len < ctx->ctx->len)
  322. return -1;
  323. switch(ctx->mode) {
  324. case LGRSAM_PKCS1_1_5:
  325. n = mbedtls_rsa_rsassa_pkcs1_v15_sign(ctx->ctx, NULL, NULL,
  326. MBEDTLS_RSA_PRIVATE,
  327. h, 0, in, sig);
  328. break;
  329. case LGRSAM_PKCS1_OAEP_PSS:
  330. n = mbedtls_rsa_rsassa_pss_sign(ctx->ctx, NULL, NULL,
  331. MBEDTLS_RSA_PRIVATE,
  332. h, 0, in, sig);
  333. break;
  334. default:
  335. return -1;
  336. }
  337. if (n < 0) {
  338. lwsl_notice("%s: -0x%x\n", __func__, -n);
  339. return -1;
  340. }
  341. return ctx->ctx->len;
  342. }
  343. int
  344. lws_genrsa_render_pkey_asn1(struct lws_genrsa_ctx *ctx, int _private,
  345. uint8_t *pkey_asn1, size_t pkey_asn1_len)
  346. {
  347. uint8_t *p = pkey_asn1, *totlen, *end = pkey_asn1 + pkey_asn1_len - 1;
  348. mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT] = {
  349. &ctx->ctx->N, &ctx->ctx->E, &ctx->ctx->D, &ctx->ctx->P,
  350. &ctx->ctx->Q, &ctx->ctx->DP, &ctx->ctx->DQ,
  351. &ctx->ctx->QP,
  352. };
  353. int n;
  354. /* 30 82 - sequence
  355. * 09 29 <-- length(0x0929) less 4 bytes
  356. * 02 01 <- length (1)
  357. * 00
  358. * 02 82
  359. * 02 01 <- length (513) N
  360. * ...
  361. *
  362. * 02 03 <- length (3) E
  363. * 01 00 01
  364. *
  365. * 02 82
  366. * 02 00 <- length (512) D P Q EXP1 EXP2 COEFF
  367. *
  368. * */
  369. *p++ = 0x30;
  370. *p++ = 0x82;
  371. totlen = p;
  372. p += 2;
  373. *p++ = 0x02;
  374. *p++ = 0x01;
  375. *p++ = 0x00;
  376. for (n = 0; n < LWS_GENCRYPTO_RSA_KEYEL_COUNT; n++) {
  377. int m = mbedtls_mpi_size(mpi[n]);
  378. uint8_t *elen;
  379. *p++ = 0x02;
  380. elen = p;
  381. if (m < 0x7f)
  382. *p++ = m;
  383. else {
  384. *p++ = 0x82;
  385. *p++ = m >> 8;
  386. *p++ = m & 0xff;
  387. }
  388. if (p + m > end)
  389. return -1;
  390. if (mbedtls_mpi_write_binary(mpi[n], p, m))
  391. return -1;
  392. if (p[0] & 0x80) {
  393. p[0] = 0x00;
  394. if (mbedtls_mpi_write_binary(mpi[n], &p[1], m))
  395. return -1;
  396. m++;
  397. }
  398. if (m < 0x7f)
  399. *elen = m;
  400. else {
  401. *elen++ = 0x82;
  402. *elen++ = m >> 8;
  403. *elen = m & 0xff;
  404. }
  405. p += m;
  406. }
  407. n = lws_ptr_diff(p, pkey_asn1);
  408. *totlen++ = (n - 4) >> 8;
  409. *totlen = (n - 4) & 0xff;
  410. return n;
  411. }
  412. void
  413. lws_genrsa_destroy(struct lws_genrsa_ctx *ctx)
  414. {
  415. if (!ctx->ctx)
  416. return;
  417. mbedtls_rsa_free(ctx->ctx);
  418. lws_free(ctx->ctx);
  419. ctx->ctx = NULL;
  420. }