lws-genec.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  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_genec provides an EC 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. const struct lws_ec_curves lws_ec_curves[] = {
  30. /*
  31. * These are the curves we are willing to use by default...
  32. *
  33. * The 3 recommended+ (P-256) and optional curves in RFC7518 7.6
  34. *
  35. * Specific keys lengths from RFC8422 p20
  36. */
  37. { "P-256", MBEDTLS_ECP_DP_SECP256R1, 32 },
  38. { "P-384", MBEDTLS_ECP_DP_SECP384R1, 48 },
  39. { "P-521", MBEDTLS_ECP_DP_SECP521R1, 66 },
  40. { NULL, 0, 0 }
  41. };
  42. static int
  43. lws_genec_keypair_import(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
  44. struct lws_gencrypto_keyelem *el)
  45. {
  46. const struct lws_ec_curves *curve;
  47. mbedtls_ecp_keypair kp;
  48. int ret = -1;
  49. if (el[LWS_GENCRYPTO_EC_KEYEL_CRV].len < 4) {
  50. lwsl_notice("%s: crv '%s' (%d)\n", __func__,
  51. el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf ?
  52. (char *)el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf :
  53. "null",
  54. el[LWS_GENCRYPTO_EC_KEYEL_CRV].len);
  55. return -21;
  56. }
  57. curve = lws_genec_curve(ctx->curve_table,
  58. (char *)el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf);
  59. if (!curve)
  60. return -22;
  61. /*
  62. * d (the private part) may be missing, otherwise it and everything
  63. * else must match the expected bignum size
  64. */
  65. if ((el[LWS_GENCRYPTO_EC_KEYEL_D].len &&
  66. el[LWS_GENCRYPTO_EC_KEYEL_D].len != curve->key_bytes) ||
  67. el[LWS_GENCRYPTO_EC_KEYEL_X].len != curve->key_bytes ||
  68. el[LWS_GENCRYPTO_EC_KEYEL_Y].len != curve->key_bytes)
  69. return -23;
  70. mbedtls_ecp_keypair_init(&kp);
  71. if (mbedtls_ecp_group_load(&kp.grp, curve->tls_lib_nid))
  72. goto bail1;
  73. ctx->has_private = !!el[LWS_GENCRYPTO_EC_KEYEL_D].len;
  74. /* d (the private key) is directly an mpi */
  75. if (ctx->has_private &&
  76. mbedtls_mpi_read_binary(&kp.d, el[LWS_GENCRYPTO_EC_KEYEL_D].buf,
  77. el[LWS_GENCRYPTO_EC_KEYEL_D].len))
  78. goto bail1;
  79. mbedtls_ecp_set_zero(&kp.Q);
  80. if (mbedtls_mpi_read_binary(&kp.Q.X, el[LWS_GENCRYPTO_EC_KEYEL_X].buf,
  81. el[LWS_GENCRYPTO_EC_KEYEL_X].len))
  82. goto bail1;
  83. if (mbedtls_mpi_read_binary(&kp.Q.Y, el[LWS_GENCRYPTO_EC_KEYEL_Y].buf,
  84. el[LWS_GENCRYPTO_EC_KEYEL_Y].len))
  85. goto bail1;
  86. mbedtls_mpi_lset(&kp.Q.Z, 1);
  87. switch (ctx->genec_alg) {
  88. case LEGENEC_ECDH:
  89. if (mbedtls_ecdh_get_params(ctx->u.ctx_ecdh, &kp,
  90. (mbedtls_ecdh_side)side))
  91. goto bail1;
  92. /* verify the key is consistent with the claimed curve */
  93. if (ctx->has_private &&
  94. mbedtls_ecp_check_privkey(&ctx->u.ctx_ecdh->grp,
  95. &ctx->u.ctx_ecdh->d))
  96. goto bail1;
  97. if (mbedtls_ecp_check_pubkey(&ctx->u.ctx_ecdh->grp,
  98. &ctx->u.ctx_ecdh->Q))
  99. goto bail1;
  100. break;
  101. case LEGENEC_ECDSA:
  102. if (mbedtls_ecdsa_from_keypair(ctx->u.ctx_ecdsa, &kp))
  103. goto bail1;
  104. /* verify the key is consistent with the claimed curve */
  105. if (ctx->has_private &&
  106. mbedtls_ecp_check_privkey(&ctx->u.ctx_ecdsa->grp,
  107. &ctx->u.ctx_ecdsa->d))
  108. goto bail1;
  109. if (mbedtls_ecp_check_pubkey(&ctx->u.ctx_ecdsa->grp,
  110. &ctx->u.ctx_ecdsa->Q))
  111. goto bail1;
  112. break;
  113. default:
  114. goto bail1;
  115. }
  116. ret = 0;
  117. bail1:
  118. mbedtls_ecp_keypair_free(&kp);
  119. return ret;
  120. }
  121. int
  122. lws_genecdh_create(struct lws_genec_ctx *ctx, struct lws_context *context,
  123. const struct lws_ec_curves *curve_table)
  124. {
  125. memset(ctx, 0, sizeof(*ctx));
  126. ctx->context = context;
  127. ctx->curve_table = curve_table;
  128. ctx->genec_alg = LEGENEC_ECDH;
  129. ctx->u.ctx_ecdh = lws_zalloc(sizeof(*ctx->u.ctx_ecdh), "genecdh");
  130. if (!ctx->u.ctx_ecdh)
  131. return 1;
  132. mbedtls_ecdh_init(ctx->u.ctx_ecdh);
  133. return 0;
  134. }
  135. int
  136. lws_genecdsa_create(struct lws_genec_ctx *ctx, struct lws_context *context,
  137. const struct lws_ec_curves *curve_table)
  138. {
  139. memset(ctx, 0, sizeof(*ctx));
  140. ctx->context = context;
  141. ctx->curve_table = curve_table;
  142. ctx->genec_alg = LEGENEC_ECDSA;
  143. ctx->u.ctx_ecdsa = lws_zalloc(sizeof(*ctx->u.ctx_ecdsa), "genecdsa");
  144. if (!ctx->u.ctx_ecdsa)
  145. return 1;
  146. mbedtls_ecdsa_init(ctx->u.ctx_ecdsa);
  147. return 0;
  148. }
  149. int
  150. lws_genecdh_set_key(struct lws_genec_ctx *ctx, struct lws_gencrypto_keyelem *el,
  151. enum enum_lws_dh_side side)
  152. {
  153. if (ctx->genec_alg != LEGENEC_ECDH)
  154. return -1;
  155. return lws_genec_keypair_import(ctx, side, el);
  156. }
  157. int
  158. lws_genecdsa_set_key(struct lws_genec_ctx *ctx,
  159. struct lws_gencrypto_keyelem *el)
  160. {
  161. if (ctx->genec_alg != LEGENEC_ECDSA)
  162. return -1;
  163. return lws_genec_keypair_import(ctx, 0, el);
  164. }
  165. void
  166. lws_genec_destroy(struct lws_genec_ctx *ctx)
  167. {
  168. switch (ctx->genec_alg) {
  169. case LEGENEC_ECDH:
  170. if (ctx->u.ctx_ecdh) {
  171. mbedtls_ecdh_free(ctx->u.ctx_ecdh);
  172. lws_free(ctx->u.ctx_ecdh);
  173. ctx->u.ctx_ecdh = NULL;
  174. }
  175. break;
  176. case LEGENEC_ECDSA:
  177. if (ctx->u.ctx_ecdsa) {
  178. mbedtls_ecdsa_free(ctx->u.ctx_ecdsa);
  179. lws_free(ctx->u.ctx_ecdsa);
  180. ctx->u.ctx_ecdsa = NULL;
  181. }
  182. break;
  183. default:
  184. break;
  185. }
  186. }
  187. int
  188. lws_genecdh_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
  189. const char *curve_name,
  190. struct lws_gencrypto_keyelem *el)
  191. {
  192. const struct lws_ec_curves *curve;
  193. mbedtls_ecdsa_context ecdsa;
  194. mbedtls_ecp_keypair *kp;
  195. mbedtls_mpi *mpi[3];
  196. int n;
  197. if (ctx->genec_alg != LEGENEC_ECDH)
  198. return -1;
  199. curve = lws_genec_curve(ctx->curve_table, curve_name);
  200. if (!curve) {
  201. lwsl_err("%s: curve '%s' not supported\n",
  202. __func__, curve_name);
  203. return -22;
  204. }
  205. mbedtls_ecdsa_init(&ecdsa);
  206. n = mbedtls_ecdsa_genkey(&ecdsa, curve->tls_lib_nid,
  207. lws_gencrypto_mbedtls_rngf,
  208. ctx->context);
  209. if (n) {
  210. lwsl_err("mbedtls_ecdsa_genkey failed 0x%x\n", -n);
  211. goto bail1;
  212. }
  213. kp = (mbedtls_ecp_keypair *)&ecdsa;
  214. n = mbedtls_ecdh_get_params(ctx->u.ctx_ecdh, kp,
  215. (mbedtls_ecdh_side)side);
  216. if (n) {
  217. lwsl_err("mbedtls_ecdh_get_params failed 0x%x\n", -n);
  218. goto bail1;
  219. }
  220. /*
  221. * we need to capture the individual element BIGNUMs into
  222. * lws_gencrypto_keyelem, so they can be serialized, used in jwk etc
  223. */
  224. mpi[0] = &kp->Q.X;
  225. mpi[1] = &kp->d;
  226. mpi[2] = &kp->Q.Y;
  227. el[LWS_GENCRYPTO_EC_KEYEL_CRV].len = strlen(curve_name) + 1;
  228. el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf =
  229. lws_malloc(el[LWS_GENCRYPTO_EC_KEYEL_CRV].len, "ec");
  230. if (!el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf)
  231. goto bail1;
  232. strcpy((char *)el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf, curve_name);
  233. for (n = LWS_GENCRYPTO_EC_KEYEL_X; n < LWS_GENCRYPTO_EC_KEYEL_COUNT;
  234. n++) {
  235. el[n].len = curve->key_bytes;
  236. el[n].buf = lws_malloc(curve->key_bytes, "ec");
  237. if (!el[n].buf)
  238. goto bail2;
  239. if (mbedtls_mpi_write_binary(mpi[n - 1], el[n].buf,
  240. curve->key_bytes))
  241. goto bail2;
  242. }
  243. mbedtls_ecdsa_free(&ecdsa);
  244. return 0;
  245. bail2:
  246. for (n = 0; n < LWS_GENCRYPTO_EC_KEYEL_COUNT; n++)
  247. if (el[n].buf)
  248. lws_free_set_NULL(el[n].buf);
  249. bail1:
  250. mbedtls_ecdsa_free(&ecdsa);
  251. lws_free_set_NULL(ctx->u.ctx_ecdh);
  252. return -1;
  253. }
  254. int
  255. lws_genecdsa_new_keypair(struct lws_genec_ctx *ctx, const char *curve_name,
  256. struct lws_gencrypto_keyelem *el)
  257. {
  258. const struct lws_ec_curves *curve;
  259. mbedtls_ecp_keypair *kp;
  260. mbedtls_mpi *mpi[3];
  261. int n;
  262. if (ctx->genec_alg != LEGENEC_ECDSA)
  263. return -1;
  264. curve = lws_genec_curve(ctx->curve_table, curve_name);
  265. if (!curve) {
  266. lwsl_err("%s: curve '%s' not supported\n",
  267. __func__, curve_name);
  268. return -22;
  269. }
  270. //mbedtls_ecdsa_init(ctx->u.ctx_ecdsa);
  271. n = mbedtls_ecdsa_genkey(ctx->u.ctx_ecdsa, curve->tls_lib_nid,
  272. lws_gencrypto_mbedtls_rngf, ctx->context);
  273. if (n) {
  274. lwsl_err("mbedtls_ecdsa_genkey failed 0x%x\n", -n);
  275. goto bail1;
  276. }
  277. /*
  278. * we need to capture the individual element BIGNUMs into
  279. * lws_gencrypto_keyelems, so they can be serialized, used in jwk etc
  280. */
  281. kp = (mbedtls_ecp_keypair *)ctx->u.ctx_ecdsa;
  282. mpi[0] = &kp->Q.X;
  283. mpi[1] = &kp->d;
  284. mpi[2] = &kp->Q.Y;
  285. el[LWS_GENCRYPTO_EC_KEYEL_CRV].len = strlen(curve_name) + 1;
  286. el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf =
  287. lws_malloc(el[LWS_GENCRYPTO_EC_KEYEL_CRV].len, "ec");
  288. if (!el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf)
  289. goto bail1;
  290. strcpy((char *)el[LWS_GENCRYPTO_EC_KEYEL_CRV].buf, curve_name);
  291. for (n = LWS_GENCRYPTO_EC_KEYEL_X; n < LWS_GENCRYPTO_EC_KEYEL_COUNT;
  292. n++) {
  293. el[n].len = curve->key_bytes;
  294. el[n].buf = lws_malloc(curve->key_bytes, "ec");
  295. if (!el[n].buf)
  296. goto bail2;
  297. if (mbedtls_mpi_write_binary(mpi[n - 1], el[n].buf, el[n].len)) {
  298. lwsl_err("%s: mbedtls_mpi_write_binary failed\n", __func__);
  299. goto bail2;
  300. }
  301. }
  302. return 0;
  303. bail2:
  304. for (n = 0; n < LWS_GENCRYPTO_EC_KEYEL_COUNT; n++)
  305. if (el[n].buf)
  306. lws_free_set_NULL(el[n].buf);
  307. bail1:
  308. lws_free_set_NULL(ctx->u.ctx_ecdsa);
  309. return -1;
  310. }
  311. int
  312. lws_genecdsa_hash_sign_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
  313. enum lws_genhash_types hash_type, int keybits,
  314. uint8_t *sig, size_t sig_len)
  315. {
  316. int n, keybytes = lws_gencrypto_bits_to_bytes(keybits);
  317. size_t hlen = lws_genhash_size(hash_type);
  318. mbedtls_mpi mpi_r, mpi_s;
  319. size_t slen = sig_len;
  320. if (ctx->genec_alg != LEGENEC_ECDSA)
  321. return -1;
  322. /*
  323. * The ECDSA P-256 SHA-256 digital signature is generated as follows:
  324. *
  325. * 1. Generate a digital signature of the JWS Signing Input using ECDSA
  326. * P-256 SHA-256 with the desired private key. The output will be
  327. * the pair (R, S), where R and S are 256-bit unsigned integers.
  328. *
  329. * 2. Turn R and S into octet sequences in big-endian order, with each
  330. * array being be 32 octets long. The octet sequence
  331. * representations MUST NOT be shortened to omit any leading zero
  332. * octets contained in the values.
  333. *
  334. * 3. Concatenate the two octet sequences in the order R and then S.
  335. * (Note that many ECDSA implementations will directly produce this
  336. * concatenation as their output.)
  337. *
  338. * 4. The resulting 64-octet sequence is the JWS Signature value.
  339. */
  340. mbedtls_mpi_init(&mpi_r);
  341. mbedtls_mpi_init(&mpi_s);
  342. n = mbedtls_ecdsa_sign(&ctx->u.ctx_ecdsa->grp, &mpi_r, &mpi_s,
  343. &ctx->u.ctx_ecdsa->d, in, hlen,
  344. lws_gencrypto_mbedtls_rngf, ctx->context);
  345. if (n) {
  346. lwsl_err("%s: mbedtls_ecdsa_sign failed: -0x%x\n",
  347. __func__, -n);
  348. goto bail2;
  349. }
  350. if (mbedtls_mpi_write_binary(&mpi_r, sig, keybytes))
  351. goto bail2;
  352. mbedtls_mpi_free(&mpi_r);
  353. if (mbedtls_mpi_write_binary(&mpi_s, sig + keybytes, keybytes))
  354. goto bail1;
  355. mbedtls_mpi_free(&mpi_s);
  356. return (int)slen;
  357. bail2:
  358. mbedtls_mpi_free(&mpi_r);
  359. bail1:
  360. mbedtls_mpi_free(&mpi_s);
  361. return -3;
  362. }
  363. int
  364. lws_genecdsa_hash_sig_verify_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
  365. enum lws_genhash_types hash_type, int keybits,
  366. const uint8_t *sig, size_t sig_len)
  367. {
  368. int n, keybytes = lws_gencrypto_bits_to_bytes(keybits);
  369. size_t hlen = lws_genhash_size(hash_type);
  370. mbedtls_mpi mpi_r, mpi_s;
  371. if (ctx->genec_alg != LEGENEC_ECDSA)
  372. return -1;
  373. if ((int)sig_len != keybytes * 2)
  374. return -1;
  375. /*
  376. * 1. The JWS Signature value MUST be a 64-octet sequence. If it is
  377. * not a 64-octet sequence, the validation has failed.
  378. *
  379. * 2. Split the 64-octet sequence into two 32-octet sequences. The
  380. * first octet sequence represents R and the second S. The values R
  381. * and S are represented as octet sequences using the Integer-to-
  382. * OctetString Conversion defined in Section 2.3.7 of SEC1 [SEC1]
  383. * (in big-endian octet order).
  384. *
  385. * 3. Submit the JWS Signing Input, R, S, and the public key (x, y) to
  386. * the ECDSA P-256 SHA-256 validator.
  387. */
  388. mbedtls_mpi_init(&mpi_r);
  389. mbedtls_mpi_init(&mpi_s);
  390. if (mbedtls_mpi_read_binary(&mpi_r, sig, keybytes))
  391. return -1;
  392. if (mbedtls_mpi_read_binary(&mpi_s, sig + keybytes, keybytes))
  393. goto bail1;
  394. n = mbedtls_ecdsa_verify(&ctx->u.ctx_ecdsa->grp, in, hlen,
  395. &ctx->u.ctx_ecdsa->Q, &mpi_r, &mpi_s);
  396. mbedtls_mpi_free(&mpi_s);
  397. mbedtls_mpi_free(&mpi_r);
  398. if (n) {
  399. lwsl_err("%s: mbedtls_ecdsa_verify failed: -0x%x\n",
  400. __func__, -n);
  401. goto bail;
  402. }
  403. return 0;
  404. bail1:
  405. mbedtls_mpi_free(&mpi_r);
  406. bail:
  407. return -3;
  408. }
  409. int
  410. lws_genecdh_compute_shared_secret(struct lws_genec_ctx *ctx, uint8_t *ss,
  411. int *ss_len)
  412. {
  413. int n;
  414. size_t st;
  415. if (mbedtls_ecp_check_pubkey(&ctx->u.ctx_ecdh->grp, &ctx->u.ctx_ecdh->Q) ||
  416. mbedtls_ecp_check_pubkey(&ctx->u.ctx_ecdh->grp, &ctx->u.ctx_ecdh->Qp)) {
  417. lwsl_err("%s: both sides must be set up\n", __func__);
  418. return -1;
  419. }
  420. n = mbedtls_ecdh_calc_secret(ctx->u.ctx_ecdh, &st, ss, *ss_len,
  421. lws_gencrypto_mbedtls_rngf, ctx->context);
  422. if (n)
  423. return -1;
  424. *ss_len = (int)st;
  425. return 0;
  426. }