ec_lib.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100
  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. const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
  68. /* functions for EC_GROUP objects */
  69. EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
  70. {
  71. EC_GROUP *ret;
  72. if (meth == NULL) {
  73. ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
  74. return NULL;
  75. }
  76. if (meth->group_init == 0) {
  77. ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  78. return NULL;
  79. }
  80. ret = OPENSSL_malloc(sizeof(*ret));
  81. if (ret == NULL) {
  82. ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
  83. return NULL;
  84. }
  85. ret->meth = meth;
  86. ret->extra_data = NULL;
  87. ret->mont_data = NULL;
  88. ret->generator = NULL;
  89. ret->order = BN_new();
  90. ret->cofactor = NULL;
  91. if (!ret->order)
  92. goto err;
  93. ret->cofactor = BN_new();
  94. if (!ret->cofactor)
  95. goto err;
  96. ret->curve_name = 0;
  97. ret->asn1_flag = OPENSSL_EC_NAMED_CURVE;
  98. ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
  99. ret->seed = NULL;
  100. ret->seed_len = 0;
  101. if (!meth->group_init(ret))
  102. goto err;
  103. return ret;
  104. err:
  105. BN_free(ret->order);
  106. BN_free(ret->cofactor);
  107. OPENSSL_free(ret);
  108. return NULL;
  109. }
  110. void EC_GROUP_free(EC_GROUP *group)
  111. {
  112. if (!group)
  113. return;
  114. if (group->meth->group_finish != 0)
  115. group->meth->group_finish(group);
  116. EC_EX_DATA_free_all_data(&group->extra_data);
  117. BN_MONT_CTX_free(group->mont_data);
  118. EC_POINT_free(group->generator);
  119. BN_free(group->order);
  120. BN_free(group->cofactor);
  121. OPENSSL_free(group->seed);
  122. OPENSSL_free(group);
  123. }
  124. void EC_GROUP_clear_free(EC_GROUP *group)
  125. {
  126. if (!group)
  127. return;
  128. if (group->meth->group_clear_finish != 0)
  129. group->meth->group_clear_finish(group);
  130. else if (group->meth->group_finish != 0)
  131. group->meth->group_finish(group);
  132. EC_EX_DATA_clear_free_all_data(&group->extra_data);
  133. BN_MONT_CTX_free(group->mont_data);
  134. EC_POINT_clear_free(group->generator);
  135. BN_clear_free(group->order);
  136. BN_clear_free(group->cofactor);
  137. OPENSSL_clear_free(group->seed, group->seed_len);
  138. OPENSSL_clear_free(group, sizeof(*group));
  139. }
  140. int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
  141. {
  142. EC_EXTRA_DATA *d;
  143. if (dest->meth->group_copy == 0) {
  144. ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  145. return 0;
  146. }
  147. if (dest->meth != src->meth) {
  148. ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
  149. return 0;
  150. }
  151. if (dest == src)
  152. return 1;
  153. EC_EX_DATA_free_all_data(&dest->extra_data);
  154. for (d = src->extra_data; d != NULL; d = d->next) {
  155. void *t = d->dup_func(d->data);
  156. if (t == NULL)
  157. return 0;
  158. if (!EC_EX_DATA_set_data
  159. (&dest->extra_data, t, d->dup_func, d->free_func,
  160. d->clear_free_func))
  161. return 0;
  162. }
  163. if (src->mont_data != NULL) {
  164. if (dest->mont_data == NULL) {
  165. dest->mont_data = BN_MONT_CTX_new();
  166. if (dest->mont_data == NULL)
  167. return 0;
  168. }
  169. if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data))
  170. return 0;
  171. } else {
  172. /* src->generator == NULL */
  173. BN_MONT_CTX_free(dest->mont_data);
  174. dest->mont_data = NULL;
  175. }
  176. if (src->generator != NULL) {
  177. if (dest->generator == NULL) {
  178. dest->generator = EC_POINT_new(dest);
  179. if (dest->generator == NULL)
  180. return 0;
  181. }
  182. if (!EC_POINT_copy(dest->generator, src->generator))
  183. return 0;
  184. } else {
  185. /* src->generator == NULL */
  186. EC_POINT_clear_free(dest->generator);
  187. dest->generator = NULL;
  188. }
  189. if (!BN_copy(dest->order, src->order))
  190. return 0;
  191. if (!BN_copy(dest->cofactor, src->cofactor))
  192. return 0;
  193. dest->curve_name = src->curve_name;
  194. dest->asn1_flag = src->asn1_flag;
  195. dest->asn1_form = src->asn1_form;
  196. if (src->seed) {
  197. OPENSSL_free(dest->seed);
  198. dest->seed = OPENSSL_malloc(src->seed_len);
  199. if (dest->seed == NULL)
  200. return 0;
  201. if (!memcpy(dest->seed, src->seed, src->seed_len))
  202. return 0;
  203. dest->seed_len = src->seed_len;
  204. } else {
  205. OPENSSL_free(dest->seed);
  206. dest->seed = NULL;
  207. dest->seed_len = 0;
  208. }
  209. return dest->meth->group_copy(dest, src);
  210. }
  211. EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
  212. {
  213. EC_GROUP *t = NULL;
  214. int ok = 0;
  215. if (a == NULL)
  216. return NULL;
  217. if ((t = EC_GROUP_new(a->meth)) == NULL)
  218. return (NULL);
  219. if (!EC_GROUP_copy(t, a))
  220. goto err;
  221. ok = 1;
  222. err:
  223. if (!ok) {
  224. EC_GROUP_free(t);
  225. return NULL;
  226. }
  227. return t;
  228. }
  229. const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
  230. {
  231. return group->meth;
  232. }
  233. int EC_METHOD_get_field_type(const EC_METHOD *meth)
  234. {
  235. return meth->field_type;
  236. }
  237. int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
  238. const BIGNUM *order, const BIGNUM *cofactor)
  239. {
  240. if (generator == NULL) {
  241. ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
  242. return 0;
  243. }
  244. if (group->generator == NULL) {
  245. group->generator = EC_POINT_new(group);
  246. if (group->generator == NULL)
  247. return 0;
  248. }
  249. if (!EC_POINT_copy(group->generator, generator))
  250. return 0;
  251. if (order != NULL) {
  252. if (!BN_copy(group->order, order))
  253. return 0;
  254. } else
  255. BN_zero(group->order);
  256. if (cofactor != NULL) {
  257. if (!BN_copy(group->cofactor, cofactor))
  258. return 0;
  259. } else
  260. BN_zero(group->cofactor);
  261. /*
  262. * We ignore the return value because some groups have an order with
  263. * factors of two, which makes the Montgomery setup fail.
  264. * |group->mont_data| will be NULL in this case.
  265. */
  266. ec_precompute_mont_data(group);
  267. return 1;
  268. }
  269. const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
  270. {
  271. return group->generator;
  272. }
  273. BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
  274. {
  275. return group->mont_data;
  276. }
  277. int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
  278. {
  279. if (!BN_copy(order, group->order))
  280. return 0;
  281. return !BN_is_zero(order);
  282. }
  283. int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
  284. BN_CTX *ctx)
  285. {
  286. if (!BN_copy(cofactor, group->cofactor))
  287. return 0;
  288. return !BN_is_zero(group->cofactor);
  289. }
  290. void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
  291. {
  292. group->curve_name = nid;
  293. }
  294. int EC_GROUP_get_curve_name(const EC_GROUP *group)
  295. {
  296. return group->curve_name;
  297. }
  298. void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
  299. {
  300. group->asn1_flag = flag;
  301. }
  302. int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
  303. {
  304. return group->asn1_flag;
  305. }
  306. void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
  307. point_conversion_form_t form)
  308. {
  309. group->asn1_form = form;
  310. }
  311. point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP
  312. *group)
  313. {
  314. return group->asn1_form;
  315. }
  316. size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
  317. {
  318. OPENSSL_free(group->seed);
  319. group->seed = NULL;
  320. group->seed_len = 0;
  321. if (!len || !p)
  322. return 1;
  323. if ((group->seed = OPENSSL_malloc(len)) == NULL)
  324. return 0;
  325. memcpy(group->seed, p, len);
  326. group->seed_len = len;
  327. return len;
  328. }
  329. unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
  330. {
  331. return group->seed;
  332. }
  333. size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
  334. {
  335. return group->seed_len;
  336. }
  337. int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
  338. const BIGNUM *b, BN_CTX *ctx)
  339. {
  340. if (group->meth->group_set_curve == 0) {
  341. ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  342. return 0;
  343. }
  344. return group->meth->group_set_curve(group, p, a, b, ctx);
  345. }
  346. int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
  347. BIGNUM *b, BN_CTX *ctx)
  348. {
  349. if (group->meth->group_get_curve == 0) {
  350. ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  351. return 0;
  352. }
  353. return group->meth->group_get_curve(group, p, a, b, ctx);
  354. }
  355. #ifndef OPENSSL_NO_EC2M
  356. int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
  357. const BIGNUM *b, BN_CTX *ctx)
  358. {
  359. if (group->meth->group_set_curve == 0) {
  360. ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M,
  361. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  362. return 0;
  363. }
  364. return group->meth->group_set_curve(group, p, a, b, ctx);
  365. }
  366. int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
  367. BIGNUM *b, BN_CTX *ctx)
  368. {
  369. if (group->meth->group_get_curve == 0) {
  370. ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M,
  371. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  372. return 0;
  373. }
  374. return group->meth->group_get_curve(group, p, a, b, ctx);
  375. }
  376. #endif
  377. int EC_GROUP_get_degree(const EC_GROUP *group)
  378. {
  379. if (group->meth->group_get_degree == 0) {
  380. ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  381. return 0;
  382. }
  383. return group->meth->group_get_degree(group);
  384. }
  385. int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
  386. {
  387. if (group->meth->group_check_discriminant == 0) {
  388. ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT,
  389. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  390. return 0;
  391. }
  392. return group->meth->group_check_discriminant(group, ctx);
  393. }
  394. int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
  395. {
  396. int r = 0;
  397. BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
  398. BN_CTX *ctx_new = NULL;
  399. /* compare the field types */
  400. if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
  401. EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
  402. return 1;
  403. /* compare the curve name (if present in both) */
  404. if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
  405. EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
  406. return 1;
  407. if (!ctx)
  408. ctx_new = ctx = BN_CTX_new();
  409. if (!ctx)
  410. return -1;
  411. BN_CTX_start(ctx);
  412. a1 = BN_CTX_get(ctx);
  413. a2 = BN_CTX_get(ctx);
  414. a3 = BN_CTX_get(ctx);
  415. b1 = BN_CTX_get(ctx);
  416. b2 = BN_CTX_get(ctx);
  417. b3 = BN_CTX_get(ctx);
  418. if (!b3) {
  419. BN_CTX_end(ctx);
  420. BN_CTX_free(ctx_new);
  421. return -1;
  422. }
  423. /*
  424. * XXX This approach assumes that the external representation of curves
  425. * over the same field type is the same.
  426. */
  427. if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
  428. !b->meth->group_get_curve(b, b1, b2, b3, ctx))
  429. r = 1;
  430. if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
  431. r = 1;
  432. /* XXX EC_POINT_cmp() assumes that the methods are equal */
  433. if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
  434. EC_GROUP_get0_generator(b), ctx))
  435. r = 1;
  436. if (!r) {
  437. /* compare the order and cofactor */
  438. if (!EC_GROUP_get_order(a, a1, ctx) ||
  439. !EC_GROUP_get_order(b, b1, ctx) ||
  440. !EC_GROUP_get_cofactor(a, a2, ctx) ||
  441. !EC_GROUP_get_cofactor(b, b2, ctx)) {
  442. BN_CTX_end(ctx);
  443. BN_CTX_free(ctx_new);
  444. return -1;
  445. }
  446. if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
  447. r = 1;
  448. }
  449. BN_CTX_end(ctx);
  450. BN_CTX_free(ctx_new);
  451. return r;
  452. }
  453. /* this has 'package' visibility */
  454. int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
  455. void *(*dup_func) (void *),
  456. void (*free_func) (void *),
  457. void (*clear_free_func) (void *))
  458. {
  459. EC_EXTRA_DATA *d;
  460. if (ex_data == NULL)
  461. return 0;
  462. for (d = *ex_data; d != NULL; d = d->next) {
  463. if (d->dup_func == dup_func && d->free_func == free_func
  464. && d->clear_free_func == clear_free_func) {
  465. ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
  466. return 0;
  467. }
  468. }
  469. if (data == NULL)
  470. /* no explicit entry needed */
  471. return 1;
  472. d = OPENSSL_malloc(sizeof(*d));
  473. if (d == NULL)
  474. return 0;
  475. d->data = data;
  476. d->dup_func = dup_func;
  477. d->free_func = free_func;
  478. d->clear_free_func = clear_free_func;
  479. d->next = *ex_data;
  480. *ex_data = d;
  481. return 1;
  482. }
  483. /* this has 'package' visibility */
  484. void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
  485. void *(*dup_func) (void *),
  486. void (*free_func) (void *),
  487. void (*clear_free_func) (void *))
  488. {
  489. const EC_EXTRA_DATA *d;
  490. for (d = ex_data; d != NULL; d = d->next) {
  491. if (d->dup_func == dup_func && d->free_func == free_func
  492. && d->clear_free_func == clear_free_func)
  493. return d->data;
  494. }
  495. return NULL;
  496. }
  497. /* this has 'package' visibility */
  498. void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
  499. void *(*dup_func) (void *),
  500. void (*free_func) (void *),
  501. void (*clear_free_func) (void *))
  502. {
  503. EC_EXTRA_DATA **p;
  504. if (ex_data == NULL)
  505. return;
  506. for (p = ex_data; *p != NULL; p = &((*p)->next)) {
  507. if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
  508. && (*p)->clear_free_func == clear_free_func) {
  509. EC_EXTRA_DATA *next = (*p)->next;
  510. (*p)->free_func((*p)->data);
  511. OPENSSL_free(*p);
  512. *p = next;
  513. return;
  514. }
  515. }
  516. }
  517. /* this has 'package' visibility */
  518. void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
  519. void *(*dup_func) (void *),
  520. void (*free_func) (void *),
  521. void (*clear_free_func) (void *))
  522. {
  523. EC_EXTRA_DATA **p;
  524. if (ex_data == NULL)
  525. return;
  526. for (p = ex_data; *p != NULL; p = &((*p)->next)) {
  527. if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
  528. && (*p)->clear_free_func == clear_free_func) {
  529. EC_EXTRA_DATA *next = (*p)->next;
  530. (*p)->clear_free_func((*p)->data);
  531. OPENSSL_free(*p);
  532. *p = next;
  533. return;
  534. }
  535. }
  536. }
  537. /* this has 'package' visibility */
  538. void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
  539. {
  540. EC_EXTRA_DATA *d;
  541. if (ex_data == NULL)
  542. return;
  543. d = *ex_data;
  544. while (d) {
  545. EC_EXTRA_DATA *next = d->next;
  546. d->free_func(d->data);
  547. OPENSSL_free(d);
  548. d = next;
  549. }
  550. *ex_data = NULL;
  551. }
  552. /* this has 'package' visibility */
  553. void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
  554. {
  555. EC_EXTRA_DATA *d;
  556. if (ex_data == NULL)
  557. return;
  558. d = *ex_data;
  559. while (d) {
  560. EC_EXTRA_DATA *next = d->next;
  561. d->clear_free_func(d->data);
  562. OPENSSL_free(d);
  563. d = next;
  564. }
  565. *ex_data = NULL;
  566. }
  567. /* functions for EC_POINT objects */
  568. EC_POINT *EC_POINT_new(const EC_GROUP *group)
  569. {
  570. EC_POINT *ret;
  571. if (group == NULL) {
  572. ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
  573. return NULL;
  574. }
  575. if (group->meth->point_init == 0) {
  576. ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  577. return NULL;
  578. }
  579. ret = OPENSSL_malloc(sizeof(*ret));
  580. if (ret == NULL) {
  581. ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
  582. return NULL;
  583. }
  584. ret->meth = group->meth;
  585. if (!ret->meth->point_init(ret)) {
  586. OPENSSL_free(ret);
  587. return NULL;
  588. }
  589. return ret;
  590. }
  591. void EC_POINT_free(EC_POINT *point)
  592. {
  593. if (!point)
  594. return;
  595. if (point->meth->point_finish != 0)
  596. point->meth->point_finish(point);
  597. OPENSSL_free(point);
  598. }
  599. void EC_POINT_clear_free(EC_POINT *point)
  600. {
  601. if (!point)
  602. return;
  603. if (point->meth->point_clear_finish != 0)
  604. point->meth->point_clear_finish(point);
  605. else if (point->meth->point_finish != 0)
  606. point->meth->point_finish(point);
  607. OPENSSL_clear_free(point, sizeof(*point));
  608. }
  609. int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
  610. {
  611. if (dest->meth->point_copy == 0) {
  612. ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  613. return 0;
  614. }
  615. if (dest->meth != src->meth) {
  616. ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
  617. return 0;
  618. }
  619. if (dest == src)
  620. return 1;
  621. return dest->meth->point_copy(dest, src);
  622. }
  623. EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
  624. {
  625. EC_POINT *t;
  626. int r;
  627. if (a == NULL)
  628. return NULL;
  629. t = EC_POINT_new(group);
  630. if (t == NULL)
  631. return (NULL);
  632. r = EC_POINT_copy(t, a);
  633. if (!r) {
  634. EC_POINT_free(t);
  635. return NULL;
  636. }
  637. return t;
  638. }
  639. const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
  640. {
  641. return point->meth;
  642. }
  643. int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
  644. {
  645. if (group->meth->point_set_to_infinity == 0) {
  646. ECerr(EC_F_EC_POINT_SET_TO_INFINITY,
  647. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  648. return 0;
  649. }
  650. if (group->meth != point->meth) {
  651. ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
  652. return 0;
  653. }
  654. return group->meth->point_set_to_infinity(group, point);
  655. }
  656. int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
  657. EC_POINT *point, const BIGNUM *x,
  658. const BIGNUM *y, const BIGNUM *z,
  659. BN_CTX *ctx)
  660. {
  661. if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
  662. ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
  663. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  664. return 0;
  665. }
  666. if (group->meth != point->meth) {
  667. ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
  668. EC_R_INCOMPATIBLE_OBJECTS);
  669. return 0;
  670. }
  671. return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x,
  672. y, z, ctx);
  673. }
  674. int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
  675. const EC_POINT *point, BIGNUM *x,
  676. BIGNUM *y, BIGNUM *z,
  677. BN_CTX *ctx)
  678. {
  679. if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
  680. ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
  681. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  682. return 0;
  683. }
  684. if (group->meth != point->meth) {
  685. ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
  686. EC_R_INCOMPATIBLE_OBJECTS);
  687. return 0;
  688. }
  689. return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x,
  690. y, z, ctx);
  691. }
  692. int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
  693. EC_POINT *point, const BIGNUM *x,
  694. const BIGNUM *y, BN_CTX *ctx)
  695. {
  696. if (group->meth->point_set_affine_coordinates == 0) {
  697. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
  698. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  699. return 0;
  700. }
  701. if (group->meth != point->meth) {
  702. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
  703. EC_R_INCOMPATIBLE_OBJECTS);
  704. return 0;
  705. }
  706. return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
  707. }
  708. #ifndef OPENSSL_NO_EC2M
  709. int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
  710. EC_POINT *point, const BIGNUM *x,
  711. const BIGNUM *y, BN_CTX *ctx)
  712. {
  713. if (group->meth->point_set_affine_coordinates == 0) {
  714. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
  715. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  716. return 0;
  717. }
  718. if (group->meth != point->meth) {
  719. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
  720. EC_R_INCOMPATIBLE_OBJECTS);
  721. return 0;
  722. }
  723. return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
  724. }
  725. #endif
  726. int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
  727. const EC_POINT *point, BIGNUM *x,
  728. BIGNUM *y, BN_CTX *ctx)
  729. {
  730. if (group->meth->point_get_affine_coordinates == 0) {
  731. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
  732. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  733. return 0;
  734. }
  735. if (group->meth != point->meth) {
  736. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
  737. EC_R_INCOMPATIBLE_OBJECTS);
  738. return 0;
  739. }
  740. return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
  741. }
  742. #ifndef OPENSSL_NO_EC2M
  743. int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
  744. const EC_POINT *point, BIGNUM *x,
  745. BIGNUM *y, BN_CTX *ctx)
  746. {
  747. if (group->meth->point_get_affine_coordinates == 0) {
  748. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
  749. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  750. return 0;
  751. }
  752. if (group->meth != point->meth) {
  753. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
  754. EC_R_INCOMPATIBLE_OBJECTS);
  755. return 0;
  756. }
  757. return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
  758. }
  759. #endif
  760. int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  761. const EC_POINT *b, BN_CTX *ctx)
  762. {
  763. if (group->meth->add == 0) {
  764. ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  765. return 0;
  766. }
  767. if ((group->meth != r->meth) || (r->meth != a->meth)
  768. || (a->meth != b->meth)) {
  769. ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
  770. return 0;
  771. }
  772. return group->meth->add(group, r, a, b, ctx);
  773. }
  774. int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  775. BN_CTX *ctx)
  776. {
  777. if (group->meth->dbl == 0) {
  778. ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  779. return 0;
  780. }
  781. if ((group->meth != r->meth) || (r->meth != a->meth)) {
  782. ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
  783. return 0;
  784. }
  785. return group->meth->dbl(group, r, a, ctx);
  786. }
  787. int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
  788. {
  789. if (group->meth->invert == 0) {
  790. ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  791. return 0;
  792. }
  793. if (group->meth != a->meth) {
  794. ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
  795. return 0;
  796. }
  797. return group->meth->invert(group, a, ctx);
  798. }
  799. int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
  800. {
  801. if (group->meth->is_at_infinity == 0) {
  802. ECerr(EC_F_EC_POINT_IS_AT_INFINITY,
  803. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  804. return 0;
  805. }
  806. if (group->meth != point->meth) {
  807. ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
  808. return 0;
  809. }
  810. return group->meth->is_at_infinity(group, point);
  811. }
  812. int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
  813. BN_CTX *ctx)
  814. {
  815. if (group->meth->is_on_curve == 0) {
  816. ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  817. return 0;
  818. }
  819. if (group->meth != point->meth) {
  820. ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
  821. return 0;
  822. }
  823. return group->meth->is_on_curve(group, point, ctx);
  824. }
  825. int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
  826. BN_CTX *ctx)
  827. {
  828. if (group->meth->point_cmp == 0) {
  829. ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  830. return -1;
  831. }
  832. if ((group->meth != a->meth) || (a->meth != b->meth)) {
  833. ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
  834. return -1;
  835. }
  836. return group->meth->point_cmp(group, a, b, ctx);
  837. }
  838. int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
  839. {
  840. if (group->meth->make_affine == 0) {
  841. ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  842. return 0;
  843. }
  844. if (group->meth != point->meth) {
  845. ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
  846. return 0;
  847. }
  848. return group->meth->make_affine(group, point, ctx);
  849. }
  850. int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
  851. EC_POINT *points[], BN_CTX *ctx)
  852. {
  853. size_t i;
  854. if (group->meth->points_make_affine == 0) {
  855. ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  856. return 0;
  857. }
  858. for (i = 0; i < num; i++) {
  859. if (group->meth != points[i]->meth) {
  860. ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
  861. return 0;
  862. }
  863. }
  864. return group->meth->points_make_affine(group, num, points, ctx);
  865. }
  866. /*
  867. * Functions for point multiplication. If group->meth->mul is 0, we use the
  868. * wNAF-based implementations in ec_mult.c; otherwise we dispatch through
  869. * methods.
  870. */
  871. int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
  872. size_t num, const EC_POINT *points[],
  873. const BIGNUM *scalars[], BN_CTX *ctx)
  874. {
  875. if (group->meth->mul == 0)
  876. /* use default */
  877. return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
  878. return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
  879. }
  880. int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
  881. const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
  882. {
  883. /* just a convenient interface to EC_POINTs_mul() */
  884. const EC_POINT *points[1];
  885. const BIGNUM *scalars[1];
  886. points[0] = point;
  887. scalars[0] = p_scalar;
  888. return EC_POINTs_mul(group, r, g_scalar,
  889. (point != NULL
  890. && p_scalar != NULL), points, scalars, ctx);
  891. }
  892. int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
  893. {
  894. if (group->meth->mul == 0)
  895. /* use default */
  896. return ec_wNAF_precompute_mult(group, ctx);
  897. if (group->meth->precompute_mult != 0)
  898. return group->meth->precompute_mult(group, ctx);
  899. else
  900. return 1; /* nothing to do, so report success */
  901. }
  902. int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
  903. {
  904. if (group->meth->mul == 0)
  905. /* use default */
  906. return ec_wNAF_have_precompute_mult(group);
  907. if (group->meth->have_precompute_mult != 0)
  908. return group->meth->have_precompute_mult(group);
  909. else
  910. return 0; /* cannot tell whether precomputation has
  911. * been performed */
  912. }
  913. /*
  914. * ec_precompute_mont_data sets |group->mont_data| from |group->order| and
  915. * returns one on success. On error it returns zero.
  916. */
  917. int ec_precompute_mont_data(EC_GROUP *group)
  918. {
  919. BN_CTX *ctx = BN_CTX_new();
  920. int ret = 0;
  921. BN_MONT_CTX_free(group->mont_data);
  922. group->mont_data = NULL;
  923. if (ctx == NULL)
  924. goto err;
  925. group->mont_data = BN_MONT_CTX_new();
  926. if (!group->mont_data)
  927. goto err;
  928. if (!BN_MONT_CTX_set(group->mont_data, group->order, ctx)) {
  929. BN_MONT_CTX_free(group->mont_data);
  930. group->mont_data = NULL;
  931. goto err;
  932. }
  933. ret = 1;
  934. err:
  935. BN_CTX_free(ctx);
  936. return ret;
  937. }