ec_lib.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  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. * [email protected].
  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. * ([email protected]). This product includes software written by Tim
  55. * Hudson ([email protected]).
  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->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. #ifndef OPENSSL_NO_EC2M
  336. int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
  337. const BIGNUM *b, BN_CTX *ctx)
  338. {
  339. if (group->meth->group_set_curve == 0) {
  340. ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M,
  341. 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_GF2m(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_GF2M,
  351. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  352. return 0;
  353. }
  354. return group->meth->group_get_curve(group, p, a, b, ctx);
  355. }
  356. #endif
  357. int EC_GROUP_get_degree(const EC_GROUP *group)
  358. {
  359. if (group->meth->group_get_degree == 0) {
  360. ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  361. return 0;
  362. }
  363. return group->meth->group_get_degree(group);
  364. }
  365. int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
  366. {
  367. if (group->meth->group_check_discriminant == 0) {
  368. ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT,
  369. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  370. return 0;
  371. }
  372. return group->meth->group_check_discriminant(group, ctx);
  373. }
  374. int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
  375. {
  376. int r = 0;
  377. BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
  378. BN_CTX *ctx_new = NULL;
  379. /* compare the field types */
  380. if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
  381. EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
  382. return 1;
  383. /* compare the curve name (if present in both) */
  384. if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
  385. EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
  386. return 1;
  387. if (!ctx)
  388. ctx_new = ctx = BN_CTX_new();
  389. if (!ctx)
  390. return -1;
  391. BN_CTX_start(ctx);
  392. a1 = BN_CTX_get(ctx);
  393. a2 = BN_CTX_get(ctx);
  394. a3 = BN_CTX_get(ctx);
  395. b1 = BN_CTX_get(ctx);
  396. b2 = BN_CTX_get(ctx);
  397. b3 = BN_CTX_get(ctx);
  398. if (!b3) {
  399. BN_CTX_end(ctx);
  400. if (ctx_new)
  401. BN_CTX_free(ctx);
  402. return -1;
  403. }
  404. /*
  405. * XXX This approach assumes that the external representation of curves
  406. * over the same field type is the same.
  407. */
  408. if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
  409. !b->meth->group_get_curve(b, b1, b2, b3, ctx))
  410. r = 1;
  411. if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
  412. r = 1;
  413. /* XXX EC_POINT_cmp() assumes that the methods are equal */
  414. if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
  415. EC_GROUP_get0_generator(b), ctx))
  416. r = 1;
  417. if (!r) {
  418. /* compare the order and cofactor */
  419. if (!EC_GROUP_get_order(a, a1, ctx) ||
  420. !EC_GROUP_get_order(b, b1, ctx) ||
  421. !EC_GROUP_get_cofactor(a, a2, ctx) ||
  422. !EC_GROUP_get_cofactor(b, b2, ctx)) {
  423. BN_CTX_end(ctx);
  424. if (ctx_new)
  425. BN_CTX_free(ctx);
  426. return -1;
  427. }
  428. if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
  429. r = 1;
  430. }
  431. BN_CTX_end(ctx);
  432. if (ctx_new)
  433. BN_CTX_free(ctx);
  434. return r;
  435. }
  436. /* this has 'package' visibility */
  437. int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
  438. void *(*dup_func) (void *),
  439. void (*free_func) (void *),
  440. void (*clear_free_func) (void *))
  441. {
  442. EC_EXTRA_DATA *d;
  443. if (ex_data == NULL)
  444. return 0;
  445. for (d = *ex_data; d != NULL; d = d->next) {
  446. if (d->dup_func == dup_func && d->free_func == free_func
  447. && d->clear_free_func == clear_free_func) {
  448. ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
  449. return 0;
  450. }
  451. }
  452. if (data == NULL)
  453. /* no explicit entry needed */
  454. return 1;
  455. d = OPENSSL_malloc(sizeof *d);
  456. if (d == NULL)
  457. return 0;
  458. d->data = data;
  459. d->dup_func = dup_func;
  460. d->free_func = free_func;
  461. d->clear_free_func = clear_free_func;
  462. d->next = *ex_data;
  463. *ex_data = d;
  464. return 1;
  465. }
  466. /* this has 'package' visibility */
  467. void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
  468. void *(*dup_func) (void *),
  469. void (*free_func) (void *),
  470. void (*clear_free_func) (void *))
  471. {
  472. const EC_EXTRA_DATA *d;
  473. for (d = ex_data; d != NULL; d = d->next) {
  474. if (d->dup_func == dup_func && d->free_func == free_func
  475. && d->clear_free_func == clear_free_func)
  476. return d->data;
  477. }
  478. return NULL;
  479. }
  480. /* this has 'package' visibility */
  481. void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
  482. void *(*dup_func) (void *),
  483. void (*free_func) (void *),
  484. void (*clear_free_func) (void *))
  485. {
  486. EC_EXTRA_DATA **p;
  487. if (ex_data == NULL)
  488. return;
  489. for (p = ex_data; *p != NULL; p = &((*p)->next)) {
  490. if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
  491. && (*p)->clear_free_func == clear_free_func) {
  492. EC_EXTRA_DATA *next = (*p)->next;
  493. (*p)->free_func((*p)->data);
  494. OPENSSL_free(*p);
  495. *p = next;
  496. return;
  497. }
  498. }
  499. }
  500. /* this has 'package' visibility */
  501. void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
  502. void *(*dup_func) (void *),
  503. void (*free_func) (void *),
  504. void (*clear_free_func) (void *))
  505. {
  506. EC_EXTRA_DATA **p;
  507. if (ex_data == NULL)
  508. return;
  509. for (p = ex_data; *p != NULL; p = &((*p)->next)) {
  510. if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
  511. && (*p)->clear_free_func == clear_free_func) {
  512. EC_EXTRA_DATA *next = (*p)->next;
  513. (*p)->clear_free_func((*p)->data);
  514. OPENSSL_free(*p);
  515. *p = next;
  516. return;
  517. }
  518. }
  519. }
  520. /* this has 'package' visibility */
  521. void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
  522. {
  523. EC_EXTRA_DATA *d;
  524. if (ex_data == NULL)
  525. return;
  526. d = *ex_data;
  527. while (d) {
  528. EC_EXTRA_DATA *next = d->next;
  529. d->free_func(d->data);
  530. OPENSSL_free(d);
  531. d = next;
  532. }
  533. *ex_data = NULL;
  534. }
  535. /* this has 'package' visibility */
  536. void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
  537. {
  538. EC_EXTRA_DATA *d;
  539. if (ex_data == NULL)
  540. return;
  541. d = *ex_data;
  542. while (d) {
  543. EC_EXTRA_DATA *next = d->next;
  544. d->clear_free_func(d->data);
  545. OPENSSL_free(d);
  546. d = next;
  547. }
  548. *ex_data = NULL;
  549. }
  550. /* functions for EC_POINT objects */
  551. EC_POINT *EC_POINT_new(const EC_GROUP *group)
  552. {
  553. EC_POINT *ret;
  554. if (group == NULL) {
  555. ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
  556. return NULL;
  557. }
  558. if (group->meth->point_init == 0) {
  559. ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  560. return NULL;
  561. }
  562. ret = OPENSSL_malloc(sizeof *ret);
  563. if (ret == NULL) {
  564. ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
  565. return NULL;
  566. }
  567. ret->meth = group->meth;
  568. if (!ret->meth->point_init(ret)) {
  569. OPENSSL_free(ret);
  570. return NULL;
  571. }
  572. return ret;
  573. }
  574. void EC_POINT_free(EC_POINT *point)
  575. {
  576. if (!point)
  577. return;
  578. if (point->meth->point_finish != 0)
  579. point->meth->point_finish(point);
  580. OPENSSL_free(point);
  581. }
  582. void EC_POINT_clear_free(EC_POINT *point)
  583. {
  584. if (!point)
  585. return;
  586. if (point->meth->point_clear_finish != 0)
  587. point->meth->point_clear_finish(point);
  588. else if (point->meth->point_finish != 0)
  589. point->meth->point_finish(point);
  590. OPENSSL_cleanse(point, sizeof *point);
  591. OPENSSL_free(point);
  592. }
  593. int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
  594. {
  595. if (dest->meth->point_copy == 0) {
  596. ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  597. return 0;
  598. }
  599. if (dest->meth != src->meth) {
  600. ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
  601. return 0;
  602. }
  603. if (dest == src)
  604. return 1;
  605. return dest->meth->point_copy(dest, src);
  606. }
  607. EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
  608. {
  609. EC_POINT *t;
  610. int r;
  611. if (a == NULL)
  612. return NULL;
  613. t = EC_POINT_new(group);
  614. if (t == NULL)
  615. return (NULL);
  616. r = EC_POINT_copy(t, a);
  617. if (!r) {
  618. EC_POINT_free(t);
  619. return NULL;
  620. } else
  621. return t;
  622. }
  623. const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
  624. {
  625. return point->meth;
  626. }
  627. int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
  628. {
  629. if (group->meth->point_set_to_infinity == 0) {
  630. ECerr(EC_F_EC_POINT_SET_TO_INFINITY,
  631. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  632. return 0;
  633. }
  634. if (group->meth != point->meth) {
  635. ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
  636. return 0;
  637. }
  638. return group->meth->point_set_to_infinity(group, point);
  639. }
  640. int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
  641. EC_POINT *point, const BIGNUM *x,
  642. const BIGNUM *y, const BIGNUM *z,
  643. BN_CTX *ctx)
  644. {
  645. if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
  646. ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
  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_JPROJECTIVE_COORDINATES_GFP,
  652. EC_R_INCOMPATIBLE_OBJECTS);
  653. return 0;
  654. }
  655. return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x,
  656. y, z, ctx);
  657. }
  658. int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
  659. const EC_POINT *point, BIGNUM *x,
  660. BIGNUM *y, BIGNUM *z,
  661. BN_CTX *ctx)
  662. {
  663. if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
  664. ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
  665. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  666. return 0;
  667. }
  668. if (group->meth != point->meth) {
  669. ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
  670. EC_R_INCOMPATIBLE_OBJECTS);
  671. return 0;
  672. }
  673. return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x,
  674. y, z, ctx);
  675. }
  676. int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
  677. EC_POINT *point, const BIGNUM *x,
  678. const BIGNUM *y, BN_CTX *ctx)
  679. {
  680. if (group->meth->point_set_affine_coordinates == 0) {
  681. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
  682. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  683. return 0;
  684. }
  685. if (group->meth != point->meth) {
  686. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
  687. EC_R_INCOMPATIBLE_OBJECTS);
  688. return 0;
  689. }
  690. return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
  691. }
  692. #ifndef OPENSSL_NO_EC2M
  693. int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
  694. EC_POINT *point, const BIGNUM *x,
  695. const BIGNUM *y, BN_CTX *ctx)
  696. {
  697. if (group->meth->point_set_affine_coordinates == 0) {
  698. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
  699. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  700. return 0;
  701. }
  702. if (group->meth != point->meth) {
  703. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
  704. EC_R_INCOMPATIBLE_OBJECTS);
  705. return 0;
  706. }
  707. return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
  708. }
  709. #endif
  710. int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
  711. const EC_POINT *point, BIGNUM *x,
  712. BIGNUM *y, BN_CTX *ctx)
  713. {
  714. if (group->meth->point_get_affine_coordinates == 0) {
  715. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
  716. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  717. return 0;
  718. }
  719. if (group->meth != point->meth) {
  720. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
  721. EC_R_INCOMPATIBLE_OBJECTS);
  722. return 0;
  723. }
  724. return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
  725. }
  726. #ifndef OPENSSL_NO_EC2M
  727. int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
  728. const EC_POINT *point, BIGNUM *x,
  729. BIGNUM *y, BN_CTX *ctx)
  730. {
  731. if (group->meth->point_get_affine_coordinates == 0) {
  732. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
  733. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  734. return 0;
  735. }
  736. if (group->meth != point->meth) {
  737. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
  738. EC_R_INCOMPATIBLE_OBJECTS);
  739. return 0;
  740. }
  741. return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
  742. }
  743. #endif
  744. int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  745. const EC_POINT *b, BN_CTX *ctx)
  746. {
  747. if (group->meth->add == 0) {
  748. ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  749. return 0;
  750. }
  751. if ((group->meth != r->meth) || (r->meth != a->meth)
  752. || (a->meth != b->meth)) {
  753. ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
  754. return 0;
  755. }
  756. return group->meth->add(group, r, a, b, ctx);
  757. }
  758. int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  759. BN_CTX *ctx)
  760. {
  761. if (group->meth->dbl == 0) {
  762. ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  763. return 0;
  764. }
  765. if ((group->meth != r->meth) || (r->meth != a->meth)) {
  766. ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
  767. return 0;
  768. }
  769. return group->meth->dbl(group, r, a, ctx);
  770. }
  771. int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
  772. {
  773. if (group->meth->invert == 0) {
  774. ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  775. return 0;
  776. }
  777. if (group->meth != a->meth) {
  778. ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
  779. return 0;
  780. }
  781. return group->meth->invert(group, a, ctx);
  782. }
  783. int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
  784. {
  785. if (group->meth->is_at_infinity == 0) {
  786. ECerr(EC_F_EC_POINT_IS_AT_INFINITY,
  787. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  788. return 0;
  789. }
  790. if (group->meth != point->meth) {
  791. ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
  792. return 0;
  793. }
  794. return group->meth->is_at_infinity(group, point);
  795. }
  796. /*
  797. * Check whether an EC_POINT is on the curve or not. Note that the return
  798. * value for this function should NOT be treated as a boolean. Return values:
  799. * 1: The point is on the curve
  800. * 0: The point is not on the curve
  801. * -1: An error occurred
  802. */
  803. int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
  804. BN_CTX *ctx)
  805. {
  806. if (group->meth->is_on_curve == 0) {
  807. ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  808. return 0;
  809. }
  810. if (group->meth != point->meth) {
  811. ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
  812. return 0;
  813. }
  814. return group->meth->is_on_curve(group, point, ctx);
  815. }
  816. int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
  817. BN_CTX *ctx)
  818. {
  819. if (group->meth->point_cmp == 0) {
  820. ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  821. return -1;
  822. }
  823. if ((group->meth != a->meth) || (a->meth != b->meth)) {
  824. ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
  825. return -1;
  826. }
  827. return group->meth->point_cmp(group, a, b, ctx);
  828. }
  829. int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
  830. {
  831. if (group->meth->make_affine == 0) {
  832. ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  833. return 0;
  834. }
  835. if (group->meth != point->meth) {
  836. ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
  837. return 0;
  838. }
  839. return group->meth->make_affine(group, point, ctx);
  840. }
  841. int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
  842. EC_POINT *points[], BN_CTX *ctx)
  843. {
  844. size_t i;
  845. if (group->meth->points_make_affine == 0) {
  846. ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  847. return 0;
  848. }
  849. for (i = 0; i < num; i++) {
  850. if (group->meth != points[i]->meth) {
  851. ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
  852. return 0;
  853. }
  854. }
  855. return group->meth->points_make_affine(group, num, points, ctx);
  856. }
  857. /*
  858. * Functions for point multiplication. If group->meth->mul is 0, we use the
  859. * wNAF-based implementations in ec_mult.c; otherwise we dispatch through
  860. * methods.
  861. */
  862. int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
  863. size_t num, const EC_POINT *points[],
  864. const BIGNUM *scalars[], BN_CTX *ctx)
  865. {
  866. if (group->meth->mul == 0)
  867. /* use default */
  868. return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
  869. return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
  870. }
  871. int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
  872. const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
  873. {
  874. /* just a convenient interface to EC_POINTs_mul() */
  875. const EC_POINT *points[1];
  876. const BIGNUM *scalars[1];
  877. points[0] = point;
  878. scalars[0] = p_scalar;
  879. return EC_POINTs_mul(group, r, g_scalar,
  880. (point != NULL
  881. && p_scalar != NULL), points, scalars, ctx);
  882. }
  883. int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
  884. {
  885. if (group->meth->mul == 0)
  886. /* use default */
  887. return ec_wNAF_precompute_mult(group, ctx);
  888. if (group->meth->precompute_mult != 0)
  889. return group->meth->precompute_mult(group, ctx);
  890. else
  891. return 1; /* nothing to do, so report success */
  892. }
  893. int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
  894. {
  895. if (group->meth->mul == 0)
  896. /* use default */
  897. return ec_wNAF_have_precompute_mult(group);
  898. if (group->meth->have_precompute_mult != 0)
  899. return group->meth->have_precompute_mult(group);
  900. else
  901. return 0; /* cannot tell whether precomputation has
  902. * been performed */
  903. }