ec_lib.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. /* crypto/ec/ec_lib.c */
  2. /*
  3. * Originally written by Bodo Moeller for the OpenSSL project.
  4. */
  5. /* ====================================================================
  6. * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. All advertising materials mentioning features or use of this
  21. * software must display the following acknowledgment:
  22. * "This product includes software developed by the OpenSSL Project
  23. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  24. *
  25. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26. * endorse or promote products derived from this software without
  27. * prior written permission. For written permission, please contact
  28. * openssl-core@openssl.org.
  29. *
  30. * 5. Products derived from this software may not be called "OpenSSL"
  31. * nor may "OpenSSL" appear in their names without prior written
  32. * permission of the OpenSSL Project.
  33. *
  34. * 6. Redistributions of any form whatsoever must retain the following
  35. * acknowledgment:
  36. * "This product includes software developed by the OpenSSL Project
  37. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  38. *
  39. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50. * OF THE POSSIBILITY OF SUCH DAMAGE.
  51. * ====================================================================
  52. *
  53. * This product includes cryptographic software written by Eric Young
  54. * (eay@cryptsoft.com). This product includes software written by Tim
  55. * Hudson (tjh@cryptsoft.com).
  56. *
  57. */
  58. /* ====================================================================
  59. * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  60. * Binary polynomial ECC support in OpenSSL originally developed by
  61. * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  62. */
  63. #include <string.h>
  64. #include <openssl/err.h>
  65. #include <openssl/opensslv.h>
  66. #include "ec_lcl.h"
  67. /* functions for EC_GROUP objects */
  68. EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
  69. {
  70. EC_GROUP *ret;
  71. if (meth == NULL) {
  72. ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
  73. return NULL;
  74. }
  75. if (meth->group_init == 0) {
  76. ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  77. return NULL;
  78. }
  79. ret = OPENSSL_zalloc(sizeof(*ret));
  80. if (ret == NULL) {
  81. ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
  82. return NULL;
  83. }
  84. ret->meth = meth;
  85. ret->order = BN_new();
  86. if (ret->order == NULL)
  87. goto err;
  88. ret->cofactor = BN_new();
  89. if (ret->cofactor == NULL)
  90. goto err;
  91. ret->asn1_flag = OPENSSL_EC_NAMED_CURVE;
  92. ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
  93. if (!meth->group_init(ret))
  94. goto err;
  95. return ret;
  96. err:
  97. BN_free(ret->order);
  98. BN_free(ret->cofactor);
  99. OPENSSL_free(ret);
  100. return NULL;
  101. }
  102. void EC_pre_comp_free(EC_GROUP *group)
  103. {
  104. switch (group->pre_comp_type) {
  105. default:
  106. break;
  107. #ifdef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
  108. case pct_nistz256:
  109. EC_nistz256_pre_comp_free(group->pre_comp.nistz256);
  110. break;
  111. #endif
  112. #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
  113. case pct_nistp224:
  114. EC_nistp224_pre_comp_free(group->pre_comp.nistp224);
  115. break;
  116. case pct_nistp256:
  117. EC_nistp256_pre_comp_free(group->pre_comp.nistp256);
  118. break;
  119. case pct_nistp521:
  120. EC_nistp521_pre_comp_free(group->pre_comp.nistp521);
  121. break;
  122. #endif
  123. case pct_ec:
  124. EC_ec_pre_comp_free(group->pre_comp.ec);
  125. break;
  126. }
  127. group->pre_comp.ec = NULL;
  128. }
  129. void EC_GROUP_free(EC_GROUP *group)
  130. {
  131. if (!group)
  132. return;
  133. if (group->meth->group_finish != 0)
  134. group->meth->group_finish(group);
  135. EC_pre_comp_free(group);
  136. BN_MONT_CTX_free(group->mont_data);
  137. EC_POINT_free(group->generator);
  138. BN_free(group->order);
  139. BN_free(group->cofactor);
  140. OPENSSL_free(group->seed);
  141. OPENSSL_free(group);
  142. }
  143. void EC_GROUP_clear_free(EC_GROUP *group)
  144. {
  145. if (!group)
  146. return;
  147. if (group->meth->group_clear_finish != 0)
  148. group->meth->group_clear_finish(group);
  149. else if (group->meth->group_finish != 0)
  150. group->meth->group_finish(group);
  151. EC_pre_comp_free(group);
  152. BN_MONT_CTX_free(group->mont_data);
  153. EC_POINT_clear_free(group->generator);
  154. BN_clear_free(group->order);
  155. BN_clear_free(group->cofactor);
  156. OPENSSL_clear_free(group->seed, group->seed_len);
  157. OPENSSL_clear_free(group, sizeof(*group));
  158. }
  159. int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
  160. {
  161. if (dest->meth->group_copy == 0) {
  162. ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  163. return 0;
  164. }
  165. if (dest->meth != src->meth) {
  166. ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
  167. return 0;
  168. }
  169. if (dest == src)
  170. return 1;
  171. /* Copy precomputed */
  172. dest->pre_comp_type = src->pre_comp_type;
  173. switch (src->pre_comp_type) {
  174. default:
  175. dest->pre_comp.ec = NULL;
  176. break;
  177. #ifdef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
  178. case pct_nistz256:
  179. dest->pre_comp.nistz256 = EC_nistz256_pre_comp_dup(src->pre_comp.nistz256);
  180. break;
  181. #endif
  182. #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
  183. case pct_nistp224:
  184. dest->pre_comp.nistp224 = EC_nistp224_pre_comp_dup(src->pre_comp.nistp224);
  185. break;
  186. case pct_nistp256:
  187. dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256);
  188. break;
  189. case pct_nistp521:
  190. dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521);
  191. break;
  192. #endif
  193. case pct_ec:
  194. dest->pre_comp.ec = EC_ec_pre_comp_dup(src->pre_comp.ec);
  195. break;
  196. }
  197. if (src->mont_data != NULL) {
  198. if (dest->mont_data == NULL) {
  199. dest->mont_data = BN_MONT_CTX_new();
  200. if (dest->mont_data == NULL)
  201. return 0;
  202. }
  203. if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data))
  204. return 0;
  205. } else {
  206. /* src->generator == NULL */
  207. BN_MONT_CTX_free(dest->mont_data);
  208. dest->mont_data = NULL;
  209. }
  210. if (src->generator != NULL) {
  211. if (dest->generator == NULL) {
  212. dest->generator = EC_POINT_new(dest);
  213. if (dest->generator == NULL)
  214. return 0;
  215. }
  216. if (!EC_POINT_copy(dest->generator, src->generator))
  217. return 0;
  218. } else {
  219. /* src->generator == NULL */
  220. EC_POINT_clear_free(dest->generator);
  221. dest->generator = NULL;
  222. }
  223. if (!BN_copy(dest->order, src->order))
  224. return 0;
  225. if (!BN_copy(dest->cofactor, src->cofactor))
  226. return 0;
  227. dest->curve_name = src->curve_name;
  228. dest->asn1_flag = src->asn1_flag;
  229. dest->asn1_form = src->asn1_form;
  230. if (src->seed) {
  231. OPENSSL_free(dest->seed);
  232. dest->seed = OPENSSL_malloc(src->seed_len);
  233. if (dest->seed == NULL)
  234. return 0;
  235. if (!memcpy(dest->seed, src->seed, src->seed_len))
  236. return 0;
  237. dest->seed_len = src->seed_len;
  238. } else {
  239. OPENSSL_free(dest->seed);
  240. dest->seed = NULL;
  241. dest->seed_len = 0;
  242. }
  243. return dest->meth->group_copy(dest, src);
  244. }
  245. EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
  246. {
  247. EC_GROUP *t = NULL;
  248. int ok = 0;
  249. if (a == NULL)
  250. return NULL;
  251. if ((t = EC_GROUP_new(a->meth)) == NULL)
  252. return (NULL);
  253. if (!EC_GROUP_copy(t, a))
  254. goto err;
  255. ok = 1;
  256. err:
  257. if (!ok) {
  258. EC_GROUP_free(t);
  259. return NULL;
  260. }
  261. return t;
  262. }
  263. const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
  264. {
  265. return group->meth;
  266. }
  267. int EC_METHOD_get_field_type(const EC_METHOD *meth)
  268. {
  269. return meth->field_type;
  270. }
  271. int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
  272. const BIGNUM *order, const BIGNUM *cofactor)
  273. {
  274. if (generator == NULL) {
  275. ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
  276. return 0;
  277. }
  278. if (group->generator == NULL) {
  279. group->generator = EC_POINT_new(group);
  280. if (group->generator == NULL)
  281. return 0;
  282. }
  283. if (!EC_POINT_copy(group->generator, generator))
  284. return 0;
  285. if (order != NULL) {
  286. if (!BN_copy(group->order, order))
  287. return 0;
  288. } else
  289. BN_zero(group->order);
  290. if (cofactor != NULL) {
  291. if (!BN_copy(group->cofactor, cofactor))
  292. return 0;
  293. } else
  294. BN_zero(group->cofactor);
  295. /*
  296. * We ignore the return value because some groups have an order with
  297. * factors of two, which makes the Montgomery setup fail.
  298. * |group->mont_data| will be NULL in this case.
  299. */
  300. ec_precompute_mont_data(group);
  301. return 1;
  302. }
  303. const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
  304. {
  305. return group->generator;
  306. }
  307. BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
  308. {
  309. return group->mont_data;
  310. }
  311. int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
  312. {
  313. if (!BN_copy(order, group->order))
  314. return 0;
  315. return !BN_is_zero(order);
  316. }
  317. int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
  318. BN_CTX *ctx)
  319. {
  320. if (!BN_copy(cofactor, group->cofactor))
  321. return 0;
  322. return !BN_is_zero(group->cofactor);
  323. }
  324. void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
  325. {
  326. group->curve_name = nid;
  327. }
  328. int EC_GROUP_get_curve_name(const EC_GROUP *group)
  329. {
  330. return group->curve_name;
  331. }
  332. void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
  333. {
  334. group->asn1_flag = flag;
  335. }
  336. int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
  337. {
  338. return group->asn1_flag;
  339. }
  340. void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
  341. point_conversion_form_t form)
  342. {
  343. group->asn1_form = form;
  344. }
  345. point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP
  346. *group)
  347. {
  348. return group->asn1_form;
  349. }
  350. size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
  351. {
  352. OPENSSL_free(group->seed);
  353. group->seed = NULL;
  354. group->seed_len = 0;
  355. if (!len || !p)
  356. return 1;
  357. if ((group->seed = OPENSSL_malloc(len)) == NULL)
  358. return 0;
  359. memcpy(group->seed, p, len);
  360. group->seed_len = len;
  361. return len;
  362. }
  363. unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
  364. {
  365. return group->seed;
  366. }
  367. size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
  368. {
  369. return group->seed_len;
  370. }
  371. int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
  372. const BIGNUM *b, BN_CTX *ctx)
  373. {
  374. if (group->meth->group_set_curve == 0) {
  375. ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  376. return 0;
  377. }
  378. return group->meth->group_set_curve(group, p, a, b, ctx);
  379. }
  380. int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
  381. BIGNUM *b, BN_CTX *ctx)
  382. {
  383. if (group->meth->group_get_curve == 0) {
  384. ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  385. return 0;
  386. }
  387. return group->meth->group_get_curve(group, p, a, b, ctx);
  388. }
  389. #ifndef OPENSSL_NO_EC2M
  390. int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
  391. const BIGNUM *b, BN_CTX *ctx)
  392. {
  393. if (group->meth->group_set_curve == 0) {
  394. ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M,
  395. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  396. return 0;
  397. }
  398. return group->meth->group_set_curve(group, p, a, b, ctx);
  399. }
  400. int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
  401. BIGNUM *b, BN_CTX *ctx)
  402. {
  403. if (group->meth->group_get_curve == 0) {
  404. ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M,
  405. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  406. return 0;
  407. }
  408. return group->meth->group_get_curve(group, p, a, b, ctx);
  409. }
  410. #endif
  411. int EC_GROUP_get_degree(const EC_GROUP *group)
  412. {
  413. if (group->meth->group_get_degree == 0) {
  414. ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  415. return 0;
  416. }
  417. return group->meth->group_get_degree(group);
  418. }
  419. int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
  420. {
  421. if (group->meth->group_check_discriminant == 0) {
  422. ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT,
  423. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  424. return 0;
  425. }
  426. return group->meth->group_check_discriminant(group, ctx);
  427. }
  428. int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
  429. {
  430. int r = 0;
  431. BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
  432. BN_CTX *ctx_new = NULL;
  433. /* compare the field types */
  434. if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
  435. EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
  436. return 1;
  437. /* compare the curve name (if present in both) */
  438. if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
  439. EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
  440. return 1;
  441. if (ctx == NULL)
  442. ctx_new = ctx = BN_CTX_new();
  443. if (ctx == NULL)
  444. return -1;
  445. BN_CTX_start(ctx);
  446. a1 = BN_CTX_get(ctx);
  447. a2 = BN_CTX_get(ctx);
  448. a3 = BN_CTX_get(ctx);
  449. b1 = BN_CTX_get(ctx);
  450. b2 = BN_CTX_get(ctx);
  451. b3 = BN_CTX_get(ctx);
  452. if (b3 == NULL) {
  453. BN_CTX_end(ctx);
  454. BN_CTX_free(ctx_new);
  455. return -1;
  456. }
  457. /*
  458. * XXX This approach assumes that the external representation of curves
  459. * over the same field type is the same.
  460. */
  461. if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
  462. !b->meth->group_get_curve(b, b1, b2, b3, ctx))
  463. r = 1;
  464. if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
  465. r = 1;
  466. /* XXX EC_POINT_cmp() assumes that the methods are equal */
  467. if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
  468. EC_GROUP_get0_generator(b), ctx))
  469. r = 1;
  470. if (!r) {
  471. /* compare the order and cofactor */
  472. if (!EC_GROUP_get_order(a, a1, ctx) ||
  473. !EC_GROUP_get_order(b, b1, ctx) ||
  474. !EC_GROUP_get_cofactor(a, a2, ctx) ||
  475. !EC_GROUP_get_cofactor(b, b2, ctx)) {
  476. BN_CTX_end(ctx);
  477. BN_CTX_free(ctx_new);
  478. return -1;
  479. }
  480. if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
  481. r = 1;
  482. }
  483. BN_CTX_end(ctx);
  484. BN_CTX_free(ctx_new);
  485. return r;
  486. }
  487. /* functions for EC_POINT objects */
  488. EC_POINT *EC_POINT_new(const EC_GROUP *group)
  489. {
  490. EC_POINT *ret;
  491. if (group == NULL) {
  492. ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
  493. return NULL;
  494. }
  495. if (group->meth->point_init == 0) {
  496. ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  497. return NULL;
  498. }
  499. ret = OPENSSL_malloc(sizeof(*ret));
  500. if (ret == NULL) {
  501. ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
  502. return NULL;
  503. }
  504. ret->meth = group->meth;
  505. if (!ret->meth->point_init(ret)) {
  506. OPENSSL_free(ret);
  507. return NULL;
  508. }
  509. return ret;
  510. }
  511. void EC_POINT_free(EC_POINT *point)
  512. {
  513. if (!point)
  514. return;
  515. if (point->meth->point_finish != 0)
  516. point->meth->point_finish(point);
  517. OPENSSL_free(point);
  518. }
  519. void EC_POINT_clear_free(EC_POINT *point)
  520. {
  521. if (!point)
  522. return;
  523. if (point->meth->point_clear_finish != 0)
  524. point->meth->point_clear_finish(point);
  525. else if (point->meth->point_finish != 0)
  526. point->meth->point_finish(point);
  527. OPENSSL_clear_free(point, sizeof(*point));
  528. }
  529. int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
  530. {
  531. if (dest->meth->point_copy == 0) {
  532. ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  533. return 0;
  534. }
  535. if (dest->meth != src->meth) {
  536. ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
  537. return 0;
  538. }
  539. if (dest == src)
  540. return 1;
  541. return dest->meth->point_copy(dest, src);
  542. }
  543. EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
  544. {
  545. EC_POINT *t;
  546. int r;
  547. if (a == NULL)
  548. return NULL;
  549. t = EC_POINT_new(group);
  550. if (t == NULL)
  551. return (NULL);
  552. r = EC_POINT_copy(t, a);
  553. if (!r) {
  554. EC_POINT_free(t);
  555. return NULL;
  556. }
  557. return t;
  558. }
  559. const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
  560. {
  561. return point->meth;
  562. }
  563. int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
  564. {
  565. if (group->meth->point_set_to_infinity == 0) {
  566. ECerr(EC_F_EC_POINT_SET_TO_INFINITY,
  567. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  568. return 0;
  569. }
  570. if (group->meth != point->meth) {
  571. ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
  572. return 0;
  573. }
  574. return group->meth->point_set_to_infinity(group, point);
  575. }
  576. int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
  577. EC_POINT *point, const BIGNUM *x,
  578. const BIGNUM *y, const BIGNUM *z,
  579. BN_CTX *ctx)
  580. {
  581. if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
  582. ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
  583. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  584. return 0;
  585. }
  586. if (group->meth != point->meth) {
  587. ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
  588. EC_R_INCOMPATIBLE_OBJECTS);
  589. return 0;
  590. }
  591. return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x,
  592. y, z, ctx);
  593. }
  594. int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
  595. const EC_POINT *point, BIGNUM *x,
  596. BIGNUM *y, BIGNUM *z,
  597. BN_CTX *ctx)
  598. {
  599. if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
  600. ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
  601. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  602. return 0;
  603. }
  604. if (group->meth != point->meth) {
  605. ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
  606. EC_R_INCOMPATIBLE_OBJECTS);
  607. return 0;
  608. }
  609. return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x,
  610. y, z, ctx);
  611. }
  612. int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
  613. EC_POINT *point, const BIGNUM *x,
  614. const BIGNUM *y, BN_CTX *ctx)
  615. {
  616. if (group->meth->point_set_affine_coordinates == 0) {
  617. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
  618. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  619. return 0;
  620. }
  621. if (group->meth != point->meth) {
  622. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
  623. EC_R_INCOMPATIBLE_OBJECTS);
  624. return 0;
  625. }
  626. return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
  627. }
  628. #ifndef OPENSSL_NO_EC2M
  629. int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
  630. EC_POINT *point, const BIGNUM *x,
  631. const BIGNUM *y, BN_CTX *ctx)
  632. {
  633. if (group->meth->point_set_affine_coordinates == 0) {
  634. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
  635. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  636. return 0;
  637. }
  638. if (group->meth != point->meth) {
  639. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
  640. EC_R_INCOMPATIBLE_OBJECTS);
  641. return 0;
  642. }
  643. return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
  644. }
  645. #endif
  646. int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
  647. const EC_POINT *point, BIGNUM *x,
  648. BIGNUM *y, BN_CTX *ctx)
  649. {
  650. if (group->meth->point_get_affine_coordinates == 0) {
  651. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
  652. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  653. return 0;
  654. }
  655. if (group->meth != point->meth) {
  656. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
  657. EC_R_INCOMPATIBLE_OBJECTS);
  658. return 0;
  659. }
  660. return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
  661. }
  662. #ifndef OPENSSL_NO_EC2M
  663. int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
  664. const EC_POINT *point, BIGNUM *x,
  665. BIGNUM *y, BN_CTX *ctx)
  666. {
  667. if (group->meth->point_get_affine_coordinates == 0) {
  668. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
  669. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  670. return 0;
  671. }
  672. if (group->meth != point->meth) {
  673. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
  674. EC_R_INCOMPATIBLE_OBJECTS);
  675. return 0;
  676. }
  677. return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
  678. }
  679. #endif
  680. int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  681. const EC_POINT *b, BN_CTX *ctx)
  682. {
  683. if (group->meth->add == 0) {
  684. ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  685. return 0;
  686. }
  687. if ((group->meth != r->meth) || (r->meth != a->meth)
  688. || (a->meth != b->meth)) {
  689. ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
  690. return 0;
  691. }
  692. return group->meth->add(group, r, a, b, ctx);
  693. }
  694. int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  695. BN_CTX *ctx)
  696. {
  697. if (group->meth->dbl == 0) {
  698. ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  699. return 0;
  700. }
  701. if ((group->meth != r->meth) || (r->meth != a->meth)) {
  702. ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
  703. return 0;
  704. }
  705. return group->meth->dbl(group, r, a, ctx);
  706. }
  707. int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
  708. {
  709. if (group->meth->invert == 0) {
  710. ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  711. return 0;
  712. }
  713. if (group->meth != a->meth) {
  714. ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
  715. return 0;
  716. }
  717. return group->meth->invert(group, a, ctx);
  718. }
  719. int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
  720. {
  721. if (group->meth->is_at_infinity == 0) {
  722. ECerr(EC_F_EC_POINT_IS_AT_INFINITY,
  723. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  724. return 0;
  725. }
  726. if (group->meth != point->meth) {
  727. ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
  728. return 0;
  729. }
  730. return group->meth->is_at_infinity(group, point);
  731. }
  732. /*
  733. * Check whether an EC_POINT is on the curve or not. Note that the return
  734. * value for this function should NOT be treated as a boolean. Return values:
  735. * 1: The point is on the curve
  736. * 0: The point is not on the curve
  737. * -1: An error occurred
  738. */
  739. int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
  740. BN_CTX *ctx)
  741. {
  742. if (group->meth->is_on_curve == 0) {
  743. ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  744. return 0;
  745. }
  746. if (group->meth != point->meth) {
  747. ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
  748. return 0;
  749. }
  750. return group->meth->is_on_curve(group, point, ctx);
  751. }
  752. int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
  753. BN_CTX *ctx)
  754. {
  755. if (group->meth->point_cmp == 0) {
  756. ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  757. return -1;
  758. }
  759. if ((group->meth != a->meth) || (a->meth != b->meth)) {
  760. ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
  761. return -1;
  762. }
  763. return group->meth->point_cmp(group, a, b, ctx);
  764. }
  765. int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
  766. {
  767. if (group->meth->make_affine == 0) {
  768. ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  769. return 0;
  770. }
  771. if (group->meth != point->meth) {
  772. ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
  773. return 0;
  774. }
  775. return group->meth->make_affine(group, point, ctx);
  776. }
  777. int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
  778. EC_POINT *points[], BN_CTX *ctx)
  779. {
  780. size_t i;
  781. if (group->meth->points_make_affine == 0) {
  782. ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  783. return 0;
  784. }
  785. for (i = 0; i < num; i++) {
  786. if (group->meth != points[i]->meth) {
  787. ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
  788. return 0;
  789. }
  790. }
  791. return group->meth->points_make_affine(group, num, points, ctx);
  792. }
  793. /*
  794. * Functions for point multiplication. If group->meth->mul is 0, we use the
  795. * wNAF-based implementations in ec_mult.c; otherwise we dispatch through
  796. * methods.
  797. */
  798. int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
  799. size_t num, const EC_POINT *points[],
  800. const BIGNUM *scalars[], BN_CTX *ctx)
  801. {
  802. if (group->meth->mul == 0)
  803. /* use default */
  804. return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
  805. return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
  806. }
  807. int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
  808. const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
  809. {
  810. /* just a convenient interface to EC_POINTs_mul() */
  811. const EC_POINT *points[1];
  812. const BIGNUM *scalars[1];
  813. points[0] = point;
  814. scalars[0] = p_scalar;
  815. return EC_POINTs_mul(group, r, g_scalar,
  816. (point != NULL
  817. && p_scalar != NULL), points, scalars, ctx);
  818. }
  819. int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
  820. {
  821. if (group->meth->mul == 0)
  822. /* use default */
  823. return ec_wNAF_precompute_mult(group, ctx);
  824. if (group->meth->precompute_mult != 0)
  825. return group->meth->precompute_mult(group, ctx);
  826. else
  827. return 1; /* nothing to do, so report success */
  828. }
  829. int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
  830. {
  831. if (group->meth->mul == 0)
  832. /* use default */
  833. return ec_wNAF_have_precompute_mult(group);
  834. if (group->meth->have_precompute_mult != 0)
  835. return group->meth->have_precompute_mult(group);
  836. else
  837. return 0; /* cannot tell whether precomputation has
  838. * been performed */
  839. }
  840. /*
  841. * ec_precompute_mont_data sets |group->mont_data| from |group->order| and
  842. * returns one on success. On error it returns zero.
  843. */
  844. int ec_precompute_mont_data(EC_GROUP *group)
  845. {
  846. BN_CTX *ctx = BN_CTX_new();
  847. int ret = 0;
  848. BN_MONT_CTX_free(group->mont_data);
  849. group->mont_data = NULL;
  850. if (ctx == NULL)
  851. goto err;
  852. group->mont_data = BN_MONT_CTX_new();
  853. if (group->mont_data == NULL)
  854. goto err;
  855. if (!BN_MONT_CTX_set(group->mont_data, group->order, ctx)) {
  856. BN_MONT_CTX_free(group->mont_data);
  857. group->mont_data = NULL;
  858. goto err;
  859. }
  860. ret = 1;
  861. err:
  862. BN_CTX_free(ctx);
  863. return ret;
  864. }
  865. int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg)
  866. {
  867. return CRYPTO_set_ex_data(&key->ex_data, idx, arg);
  868. }
  869. void *EC_KEY_get_ex_data(const EC_KEY *key, int idx)
  870. {
  871. return CRYPTO_get_ex_data(&key->ex_data, idx);
  872. }