ec_lib.c 31 KB

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