2
0

ec_lib.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316
  1. /* crypto/ec/ec_lib.c */
  2. /*
  3. * Originally written by Bodo Moeller for the OpenSSL project.
  4. */
  5. /* ====================================================================
  6. * Copyright (c) 1998-2019 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. /* local function prototypes */
  69. static int ec_precompute_mont_data(EC_GROUP *group);
  70. /* functions for EC_GROUP objects */
  71. EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
  72. {
  73. EC_GROUP *ret;
  74. if (meth == NULL) {
  75. ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
  76. return NULL;
  77. }
  78. if (meth->group_init == 0) {
  79. ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  80. return NULL;
  81. }
  82. ret = OPENSSL_malloc(sizeof(*ret));
  83. if (ret == NULL) {
  84. ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
  85. return NULL;
  86. }
  87. ret->meth = meth;
  88. ret->extra_data = NULL;
  89. ret->mont_data = NULL;
  90. ret->generator = NULL;
  91. BN_init(&ret->order);
  92. BN_init(&ret->cofactor);
  93. ret->curve_name = 0;
  94. ret->asn1_flag = ~EC_GROUP_ASN1_FLAG_MASK;
  95. ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
  96. ret->seed = NULL;
  97. ret->seed_len = 0;
  98. if (!meth->group_init(ret)) {
  99. OPENSSL_free(ret);
  100. return NULL;
  101. }
  102. return ret;
  103. }
  104. void EC_GROUP_free(EC_GROUP *group)
  105. {
  106. if (!group)
  107. return;
  108. if (group->meth->group_finish != 0)
  109. group->meth->group_finish(group);
  110. EC_EX_DATA_free_all_data(&group->extra_data);
  111. if (EC_GROUP_VERSION(group) && group->mont_data)
  112. BN_MONT_CTX_free(group->mont_data);
  113. if (group->generator != NULL)
  114. EC_POINT_free(group->generator);
  115. BN_free(&group->order);
  116. BN_free(&group->cofactor);
  117. if (group->seed)
  118. OPENSSL_free(group->seed);
  119. OPENSSL_free(group);
  120. }
  121. void EC_GROUP_clear_free(EC_GROUP *group)
  122. {
  123. if (!group)
  124. return;
  125. if (group->meth->group_clear_finish != 0)
  126. group->meth->group_clear_finish(group);
  127. else if (group->meth->group_finish != 0)
  128. group->meth->group_finish(group);
  129. EC_EX_DATA_clear_free_all_data(&group->extra_data);
  130. if (EC_GROUP_VERSION(group) && group->mont_data)
  131. BN_MONT_CTX_free(group->mont_data);
  132. if (group->generator != NULL)
  133. EC_POINT_clear_free(group->generator);
  134. BN_clear_free(&group->order);
  135. BN_clear_free(&group->cofactor);
  136. if (group->seed) {
  137. OPENSSL_cleanse(group->seed, group->seed_len);
  138. OPENSSL_free(group->seed);
  139. }
  140. OPENSSL_cleanse(group, sizeof(*group));
  141. OPENSSL_free(group);
  142. }
  143. int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
  144. {
  145. EC_EXTRA_DATA *d;
  146. if (dest->meth->group_copy == 0) {
  147. ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  148. return 0;
  149. }
  150. if (dest->meth != src->meth) {
  151. ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
  152. return 0;
  153. }
  154. if (dest == src)
  155. return 1;
  156. EC_EX_DATA_free_all_data(&dest->extra_data);
  157. for (d = src->extra_data; d != NULL; d = d->next) {
  158. void *t = d->dup_func(d->data);
  159. if (t == NULL)
  160. return 0;
  161. if (!EC_EX_DATA_set_data
  162. (&dest->extra_data, t, d->dup_func, d->free_func,
  163. d->clear_free_func))
  164. return 0;
  165. }
  166. if (EC_GROUP_VERSION(src) && src->mont_data != NULL) {
  167. if (dest->mont_data == NULL) {
  168. dest->mont_data = BN_MONT_CTX_new();
  169. if (dest->mont_data == NULL)
  170. return 0;
  171. }
  172. if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data))
  173. return 0;
  174. } else {
  175. /* src->generator == NULL */
  176. if (EC_GROUP_VERSION(dest) && dest->mont_data != NULL) {
  177. BN_MONT_CTX_free(dest->mont_data);
  178. dest->mont_data = NULL;
  179. }
  180. }
  181. if (src->generator != NULL) {
  182. if (dest->generator == NULL) {
  183. dest->generator = EC_POINT_new(dest);
  184. if (dest->generator == NULL)
  185. return 0;
  186. }
  187. if (!EC_POINT_copy(dest->generator, src->generator))
  188. return 0;
  189. } else {
  190. /* src->generator == NULL */
  191. if (dest->generator != NULL) {
  192. EC_POINT_clear_free(dest->generator);
  193. dest->generator = NULL;
  194. }
  195. }
  196. if (!BN_copy(&dest->order, &src->order))
  197. return 0;
  198. if (!BN_copy(&dest->cofactor, &src->cofactor))
  199. return 0;
  200. dest->curve_name = src->curve_name;
  201. dest->asn1_flag = src->asn1_flag;
  202. dest->asn1_form = src->asn1_form;
  203. if (src->seed) {
  204. if (dest->seed)
  205. OPENSSL_free(dest->seed);
  206. dest->seed = OPENSSL_malloc(src->seed_len);
  207. if (dest->seed == NULL)
  208. return 0;
  209. if (!memcpy(dest->seed, src->seed, src->seed_len))
  210. return 0;
  211. dest->seed_len = src->seed_len;
  212. } else {
  213. if (dest->seed)
  214. OPENSSL_free(dest->seed);
  215. dest->seed = NULL;
  216. dest->seed_len = 0;
  217. }
  218. return dest->meth->group_copy(dest, src);
  219. }
  220. EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
  221. {
  222. EC_GROUP *t = NULL;
  223. int ok = 0;
  224. if (a == NULL)
  225. return NULL;
  226. if ((t = EC_GROUP_new(a->meth)) == NULL)
  227. return (NULL);
  228. if (!EC_GROUP_copy(t, a))
  229. goto err;
  230. ok = 1;
  231. err:
  232. if (!ok) {
  233. if (t)
  234. EC_GROUP_free(t);
  235. return NULL;
  236. } else
  237. return t;
  238. }
  239. const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
  240. {
  241. return group->meth;
  242. }
  243. int EC_METHOD_get_field_type(const EC_METHOD *meth)
  244. {
  245. return meth->field_type;
  246. }
  247. /*-
  248. * Try computing cofactor from the generator order (n) and field cardinality (q).
  249. * This works for all curves of cryptographic interest.
  250. *
  251. * Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q)
  252. * h_min = (q + 1 - 2*sqrt(q))/n
  253. * h_max = (q + 1 + 2*sqrt(q))/n
  254. * h_max - h_min = 4*sqrt(q)/n
  255. * So if n > 4*sqrt(q) holds, there is only one possible value for h:
  256. * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil
  257. *
  258. * Otherwise, zero cofactor and return success.
  259. */
  260. static int ec_guess_cofactor(EC_GROUP *group) {
  261. int ret = 0;
  262. BN_CTX *ctx = NULL;
  263. BIGNUM *q = NULL;
  264. /*-
  265. * If the cofactor is too large, we cannot guess it.
  266. * The RHS of below is a strict overestimate of lg(4 * sqrt(q))
  267. */
  268. if (BN_num_bits(&group->order) <= (BN_num_bits(&group->field) + 1) / 2 + 3) {
  269. /* default to 0 */
  270. BN_zero(&group->cofactor);
  271. /* return success */
  272. return 1;
  273. }
  274. if ((ctx = BN_CTX_new()) == NULL)
  275. return 0;
  276. BN_CTX_start(ctx);
  277. if ((q = BN_CTX_get(ctx)) == NULL)
  278. goto err;
  279. /* set q = 2**m for binary fields; q = p otherwise */
  280. if (group->meth->field_type == NID_X9_62_characteristic_two_field) {
  281. BN_zero(q);
  282. if (!BN_set_bit(q, BN_num_bits(&group->field) - 1))
  283. goto err;
  284. } else {
  285. if (!BN_copy(q, &group->field))
  286. goto err;
  287. }
  288. /* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */
  289. if (!BN_rshift1(&group->cofactor, &group->order) /* n/2 */
  290. || !BN_add(&group->cofactor, &group->cofactor, q) /* q + n/2 */
  291. /* q + 1 + n/2 */
  292. || !BN_add(&group->cofactor, &group->cofactor, BN_value_one())
  293. /* (q + 1 + n/2)/n */
  294. || !BN_div(&group->cofactor, NULL, &group->cofactor, &group->order, ctx))
  295. goto err;
  296. ret = 1;
  297. err:
  298. BN_CTX_end(ctx);
  299. BN_CTX_free(ctx);
  300. return ret;
  301. }
  302. int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
  303. const BIGNUM *order, const BIGNUM *cofactor)
  304. {
  305. if (generator == NULL) {
  306. ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
  307. return 0;
  308. }
  309. /* require group->field >= 1 */
  310. if (BN_is_zero(&group->field) || BN_is_negative(&group->field)) {
  311. ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_FIELD);
  312. return 0;
  313. }
  314. /*-
  315. * - require order >= 1
  316. * - enforce upper bound due to Hasse thm: order can be no more than one bit
  317. * longer than field cardinality
  318. */
  319. if (order == NULL || BN_is_zero(order) || BN_is_negative(order)
  320. || BN_num_bits(order) > BN_num_bits(&group->field) + 1) {
  321. ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_GROUP_ORDER);
  322. return 0;
  323. }
  324. /*-
  325. * Unfortunately the cofactor is an optional field in many standards.
  326. * Internally, the lib uses 0 cofactor as a marker for "unknown cofactor".
  327. * So accept cofactor == NULL or cofactor >= 0.
  328. */
  329. if (cofactor != NULL && BN_is_negative(cofactor)) {
  330. ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_UNKNOWN_COFACTOR);
  331. return 0;
  332. }
  333. if (group->generator == NULL) {
  334. group->generator = EC_POINT_new(group);
  335. if (group->generator == NULL)
  336. return 0;
  337. }
  338. if (!EC_POINT_copy(group->generator, generator))
  339. return 0;
  340. if (!BN_copy(&group->order, order))
  341. return 0;
  342. /* Either take the provided positive cofactor, or try to compute it */
  343. if (cofactor != NULL && !BN_is_zero(cofactor)) {
  344. if (!BN_copy(&group->cofactor, cofactor))
  345. return 0;
  346. } else if (!ec_guess_cofactor(group)) {
  347. BN_zero(&group->cofactor);
  348. return 0;
  349. }
  350. /*-
  351. * Access to the `mont_data` field of an EC_GROUP struct should always be
  352. * guarded by an EC_GROUP_VERSION(group) check to avoid OOB accesses, as the
  353. * group might come from the FIPS module, which does not define the
  354. * `mont_data` field inside the EC_GROUP structure.
  355. */
  356. if (EC_GROUP_VERSION(group)) {
  357. /*-
  358. * Some groups have an order with
  359. * factors of two, which makes the Montgomery setup fail.
  360. * |group->mont_data| will be NULL in this case.
  361. */
  362. if (BN_is_odd(&group->order))
  363. return ec_precompute_mont_data(group);
  364. BN_MONT_CTX_free(group->mont_data);
  365. group->mont_data = NULL;
  366. }
  367. return 1;
  368. }
  369. const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
  370. {
  371. return group->generator;
  372. }
  373. BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
  374. {
  375. return EC_GROUP_VERSION(group) ? group->mont_data : NULL;
  376. }
  377. int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
  378. {
  379. if (!BN_copy(order, &group->order))
  380. return 0;
  381. return !BN_is_zero(order);
  382. }
  383. int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
  384. BN_CTX *ctx)
  385. {
  386. if (!BN_copy(cofactor, &group->cofactor))
  387. return 0;
  388. return !BN_is_zero(&group->cofactor);
  389. }
  390. void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
  391. {
  392. group->curve_name = nid;
  393. }
  394. int EC_GROUP_get_curve_name(const EC_GROUP *group)
  395. {
  396. return group->curve_name;
  397. }
  398. void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
  399. {
  400. group->asn1_flag &= ~EC_GROUP_ASN1_FLAG_MASK;
  401. group->asn1_flag |= flag & EC_GROUP_ASN1_FLAG_MASK;
  402. }
  403. int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
  404. {
  405. return group->asn1_flag & EC_GROUP_ASN1_FLAG_MASK;
  406. }
  407. void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
  408. point_conversion_form_t form)
  409. {
  410. group->asn1_form = form;
  411. }
  412. point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP
  413. *group)
  414. {
  415. return group->asn1_form;
  416. }
  417. size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
  418. {
  419. if (group->seed) {
  420. OPENSSL_free(group->seed);
  421. group->seed = NULL;
  422. group->seed_len = 0;
  423. }
  424. if (!len || !p)
  425. return 1;
  426. if ((group->seed = OPENSSL_malloc(len)) == NULL)
  427. return 0;
  428. memcpy(group->seed, p, len);
  429. group->seed_len = len;
  430. return len;
  431. }
  432. unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
  433. {
  434. return group->seed;
  435. }
  436. size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
  437. {
  438. return group->seed_len;
  439. }
  440. int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
  441. const BIGNUM *b, BN_CTX *ctx)
  442. {
  443. if (group->meth->group_set_curve == 0) {
  444. ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  445. return 0;
  446. }
  447. return group->meth->group_set_curve(group, p, a, b, ctx);
  448. }
  449. int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
  450. BIGNUM *b, BN_CTX *ctx)
  451. {
  452. if (group->meth->group_get_curve == 0) {
  453. ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  454. return 0;
  455. }
  456. return group->meth->group_get_curve(group, p, a, b, ctx);
  457. }
  458. #ifndef OPENSSL_NO_EC2M
  459. int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
  460. const BIGNUM *b, BN_CTX *ctx)
  461. {
  462. if (group->meth->group_set_curve == 0) {
  463. ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M,
  464. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  465. return 0;
  466. }
  467. return group->meth->group_set_curve(group, p, a, b, ctx);
  468. }
  469. int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
  470. BIGNUM *b, BN_CTX *ctx)
  471. {
  472. if (group->meth->group_get_curve == 0) {
  473. ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M,
  474. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  475. return 0;
  476. }
  477. return group->meth->group_get_curve(group, p, a, b, ctx);
  478. }
  479. #endif
  480. int EC_GROUP_get_degree(const EC_GROUP *group)
  481. {
  482. if (group->meth->group_get_degree == 0) {
  483. ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  484. return 0;
  485. }
  486. return group->meth->group_get_degree(group);
  487. }
  488. int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
  489. {
  490. if (group->meth->group_check_discriminant == 0) {
  491. ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT,
  492. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  493. return 0;
  494. }
  495. return group->meth->group_check_discriminant(group, ctx);
  496. }
  497. int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
  498. {
  499. int r = 0;
  500. BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
  501. BN_CTX *ctx_new = NULL;
  502. /* compare the field types */
  503. if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
  504. EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
  505. return 1;
  506. /* compare the curve name (if present in both) */
  507. if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
  508. EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
  509. return 1;
  510. if (!ctx)
  511. ctx_new = ctx = BN_CTX_new();
  512. if (!ctx)
  513. return -1;
  514. BN_CTX_start(ctx);
  515. a1 = BN_CTX_get(ctx);
  516. a2 = BN_CTX_get(ctx);
  517. a3 = BN_CTX_get(ctx);
  518. b1 = BN_CTX_get(ctx);
  519. b2 = BN_CTX_get(ctx);
  520. b3 = BN_CTX_get(ctx);
  521. if (!b3) {
  522. BN_CTX_end(ctx);
  523. if (ctx_new)
  524. BN_CTX_free(ctx);
  525. return -1;
  526. }
  527. /*
  528. * XXX This approach assumes that the external representation of curves
  529. * over the same field type is the same.
  530. */
  531. if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
  532. !b->meth->group_get_curve(b, b1, b2, b3, ctx))
  533. r = 1;
  534. if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
  535. r = 1;
  536. /* XXX EC_POINT_cmp() assumes that the methods are equal */
  537. if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
  538. EC_GROUP_get0_generator(b), ctx))
  539. r = 1;
  540. if (!r) {
  541. /* compare the order and cofactor */
  542. if (!EC_GROUP_get_order(a, a1, ctx) ||
  543. !EC_GROUP_get_order(b, b1, ctx) ||
  544. !EC_GROUP_get_cofactor(a, a2, ctx) ||
  545. !EC_GROUP_get_cofactor(b, b2, ctx)) {
  546. BN_CTX_end(ctx);
  547. if (ctx_new)
  548. BN_CTX_free(ctx);
  549. return -1;
  550. }
  551. if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
  552. r = 1;
  553. }
  554. BN_CTX_end(ctx);
  555. if (ctx_new)
  556. BN_CTX_free(ctx);
  557. return r;
  558. }
  559. /* this has 'package' visibility */
  560. int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
  561. void *(*dup_func) (void *),
  562. void (*free_func) (void *),
  563. void (*clear_free_func) (void *))
  564. {
  565. EC_EXTRA_DATA *d;
  566. if (ex_data == NULL)
  567. return 0;
  568. for (d = *ex_data; d != NULL; d = d->next) {
  569. if (d->dup_func == dup_func && d->free_func == free_func
  570. && d->clear_free_func == clear_free_func) {
  571. ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
  572. return 0;
  573. }
  574. }
  575. if (data == NULL)
  576. /* no explicit entry needed */
  577. return 1;
  578. d = OPENSSL_malloc(sizeof(*d));
  579. if (d == NULL)
  580. return 0;
  581. d->data = data;
  582. d->dup_func = dup_func;
  583. d->free_func = free_func;
  584. d->clear_free_func = clear_free_func;
  585. d->next = *ex_data;
  586. *ex_data = d;
  587. return 1;
  588. }
  589. /* this has 'package' visibility */
  590. void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
  591. void *(*dup_func) (void *),
  592. void (*free_func) (void *),
  593. void (*clear_free_func) (void *))
  594. {
  595. const EC_EXTRA_DATA *d;
  596. for (d = ex_data; d != NULL; d = d->next) {
  597. if (d->dup_func == dup_func && d->free_func == free_func
  598. && d->clear_free_func == clear_free_func)
  599. return d->data;
  600. }
  601. return NULL;
  602. }
  603. /* this has 'package' visibility */
  604. void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
  605. void *(*dup_func) (void *),
  606. void (*free_func) (void *),
  607. void (*clear_free_func) (void *))
  608. {
  609. EC_EXTRA_DATA **p;
  610. if (ex_data == NULL)
  611. return;
  612. for (p = ex_data; *p != NULL; p = &((*p)->next)) {
  613. if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
  614. && (*p)->clear_free_func == clear_free_func) {
  615. EC_EXTRA_DATA *next = (*p)->next;
  616. (*p)->free_func((*p)->data);
  617. OPENSSL_free(*p);
  618. *p = next;
  619. return;
  620. }
  621. }
  622. }
  623. /* this has 'package' visibility */
  624. void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
  625. void *(*dup_func) (void *),
  626. void (*free_func) (void *),
  627. void (*clear_free_func) (void *))
  628. {
  629. EC_EXTRA_DATA **p;
  630. if (ex_data == NULL)
  631. return;
  632. for (p = ex_data; *p != NULL; p = &((*p)->next)) {
  633. if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
  634. && (*p)->clear_free_func == clear_free_func) {
  635. EC_EXTRA_DATA *next = (*p)->next;
  636. (*p)->clear_free_func((*p)->data);
  637. OPENSSL_free(*p);
  638. *p = next;
  639. return;
  640. }
  641. }
  642. }
  643. /* this has 'package' visibility */
  644. void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
  645. {
  646. EC_EXTRA_DATA *d;
  647. if (ex_data == NULL)
  648. return;
  649. d = *ex_data;
  650. while (d) {
  651. EC_EXTRA_DATA *next = d->next;
  652. d->free_func(d->data);
  653. OPENSSL_free(d);
  654. d = next;
  655. }
  656. *ex_data = NULL;
  657. }
  658. /* this has 'package' visibility */
  659. void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
  660. {
  661. EC_EXTRA_DATA *d;
  662. if (ex_data == NULL)
  663. return;
  664. d = *ex_data;
  665. while (d) {
  666. EC_EXTRA_DATA *next = d->next;
  667. d->clear_free_func(d->data);
  668. OPENSSL_free(d);
  669. d = next;
  670. }
  671. *ex_data = NULL;
  672. }
  673. /* functions for EC_POINT objects */
  674. EC_POINT *EC_POINT_new(const EC_GROUP *group)
  675. {
  676. EC_POINT *ret;
  677. if (group == NULL) {
  678. ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
  679. return NULL;
  680. }
  681. if (group->meth->point_init == 0) {
  682. ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  683. return NULL;
  684. }
  685. ret = OPENSSL_malloc(sizeof(*ret));
  686. if (ret == NULL) {
  687. ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
  688. return NULL;
  689. }
  690. ret->meth = group->meth;
  691. if (!ret->meth->point_init(ret)) {
  692. OPENSSL_free(ret);
  693. return NULL;
  694. }
  695. return ret;
  696. }
  697. void EC_POINT_free(EC_POINT *point)
  698. {
  699. if (!point)
  700. return;
  701. if (point->meth->point_finish != 0)
  702. point->meth->point_finish(point);
  703. OPENSSL_free(point);
  704. }
  705. void EC_POINT_clear_free(EC_POINT *point)
  706. {
  707. if (!point)
  708. return;
  709. if (point->meth->point_clear_finish != 0)
  710. point->meth->point_clear_finish(point);
  711. else if (point->meth->point_finish != 0)
  712. point->meth->point_finish(point);
  713. OPENSSL_cleanse(point, sizeof(*point));
  714. OPENSSL_free(point);
  715. }
  716. int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
  717. {
  718. if (dest->meth->point_copy == 0) {
  719. ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  720. return 0;
  721. }
  722. if (dest->meth != src->meth) {
  723. ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
  724. return 0;
  725. }
  726. if (dest == src)
  727. return 1;
  728. return dest->meth->point_copy(dest, src);
  729. }
  730. EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
  731. {
  732. EC_POINT *t;
  733. int r;
  734. if (a == NULL)
  735. return NULL;
  736. t = EC_POINT_new(group);
  737. if (t == NULL)
  738. return (NULL);
  739. r = EC_POINT_copy(t, a);
  740. if (!r) {
  741. EC_POINT_free(t);
  742. return NULL;
  743. } else
  744. return t;
  745. }
  746. const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
  747. {
  748. return point->meth;
  749. }
  750. int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
  751. {
  752. if (group->meth->point_set_to_infinity == 0) {
  753. ECerr(EC_F_EC_POINT_SET_TO_INFINITY,
  754. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  755. return 0;
  756. }
  757. if (group->meth != point->meth) {
  758. ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
  759. return 0;
  760. }
  761. return group->meth->point_set_to_infinity(group, point);
  762. }
  763. int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
  764. EC_POINT *point, const BIGNUM *x,
  765. const BIGNUM *y, const BIGNUM *z,
  766. BN_CTX *ctx)
  767. {
  768. if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
  769. ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
  770. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  771. return 0;
  772. }
  773. if (group->meth != point->meth) {
  774. ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
  775. EC_R_INCOMPATIBLE_OBJECTS);
  776. return 0;
  777. }
  778. return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x,
  779. y, z, ctx);
  780. }
  781. int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
  782. const EC_POINT *point, BIGNUM *x,
  783. BIGNUM *y, BIGNUM *z,
  784. BN_CTX *ctx)
  785. {
  786. if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
  787. ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
  788. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  789. return 0;
  790. }
  791. if (group->meth != point->meth) {
  792. ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
  793. EC_R_INCOMPATIBLE_OBJECTS);
  794. return 0;
  795. }
  796. return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x,
  797. y, z, ctx);
  798. }
  799. int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
  800. EC_POINT *point, const BIGNUM *x,
  801. const BIGNUM *y, BN_CTX *ctx)
  802. {
  803. if (group->meth->point_set_affine_coordinates == 0) {
  804. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
  805. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  806. return 0;
  807. }
  808. if (group->meth != point->meth) {
  809. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
  810. EC_R_INCOMPATIBLE_OBJECTS);
  811. return 0;
  812. }
  813. if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
  814. return 0;
  815. if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
  816. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
  817. EC_R_POINT_IS_NOT_ON_CURVE);
  818. return 0;
  819. }
  820. return 1;
  821. }
  822. #ifndef OPENSSL_NO_EC2M
  823. int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
  824. EC_POINT *point, const BIGNUM *x,
  825. const BIGNUM *y, BN_CTX *ctx)
  826. {
  827. if (group->meth->point_set_affine_coordinates == 0) {
  828. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
  829. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  830. return 0;
  831. }
  832. if (group->meth != point->meth) {
  833. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
  834. EC_R_INCOMPATIBLE_OBJECTS);
  835. return 0;
  836. }
  837. if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
  838. return 0;
  839. if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
  840. ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
  841. EC_R_POINT_IS_NOT_ON_CURVE);
  842. return 0;
  843. }
  844. return 1;
  845. }
  846. #endif
  847. int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
  848. const EC_POINT *point, BIGNUM *x,
  849. BIGNUM *y, BN_CTX *ctx)
  850. {
  851. if (group->meth->point_get_affine_coordinates == 0) {
  852. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
  853. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  854. return 0;
  855. }
  856. if (group->meth != point->meth) {
  857. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
  858. EC_R_INCOMPATIBLE_OBJECTS);
  859. return 0;
  860. }
  861. return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
  862. }
  863. #ifndef OPENSSL_NO_EC2M
  864. int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
  865. const EC_POINT *point, BIGNUM *x,
  866. BIGNUM *y, BN_CTX *ctx)
  867. {
  868. if (group->meth->point_get_affine_coordinates == 0) {
  869. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
  870. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  871. return 0;
  872. }
  873. if (group->meth != point->meth) {
  874. ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
  875. EC_R_INCOMPATIBLE_OBJECTS);
  876. return 0;
  877. }
  878. return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
  879. }
  880. #endif
  881. int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  882. const EC_POINT *b, BN_CTX *ctx)
  883. {
  884. if (group->meth->add == 0) {
  885. ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  886. return 0;
  887. }
  888. if ((group->meth != r->meth) || (r->meth != a->meth)
  889. || (a->meth != b->meth)) {
  890. ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
  891. return 0;
  892. }
  893. return group->meth->add(group, r, a, b, ctx);
  894. }
  895. int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  896. BN_CTX *ctx)
  897. {
  898. if (group->meth->dbl == 0) {
  899. ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  900. return 0;
  901. }
  902. if ((group->meth != r->meth) || (r->meth != a->meth)) {
  903. ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
  904. return 0;
  905. }
  906. return group->meth->dbl(group, r, a, ctx);
  907. }
  908. int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
  909. {
  910. if (group->meth->invert == 0) {
  911. ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  912. return 0;
  913. }
  914. if (group->meth != a->meth) {
  915. ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
  916. return 0;
  917. }
  918. return group->meth->invert(group, a, ctx);
  919. }
  920. int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
  921. {
  922. if (group->meth->is_at_infinity == 0) {
  923. ECerr(EC_F_EC_POINT_IS_AT_INFINITY,
  924. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  925. return 0;
  926. }
  927. if (group->meth != point->meth) {
  928. ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
  929. return 0;
  930. }
  931. return group->meth->is_at_infinity(group, point);
  932. }
  933. /*
  934. * Check whether an EC_POINT is on the curve or not. Note that the return
  935. * value for this function should NOT be treated as a boolean. Return values:
  936. * 1: The point is on the curve
  937. * 0: The point is not on the curve
  938. * -1: An error occurred
  939. */
  940. int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
  941. BN_CTX *ctx)
  942. {
  943. if (group->meth->is_on_curve == 0) {
  944. ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  945. return 0;
  946. }
  947. if (group->meth != point->meth) {
  948. ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
  949. return 0;
  950. }
  951. return group->meth->is_on_curve(group, point, ctx);
  952. }
  953. int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
  954. BN_CTX *ctx)
  955. {
  956. if (group->meth->point_cmp == 0) {
  957. ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  958. return -1;
  959. }
  960. if ((group->meth != a->meth) || (a->meth != b->meth)) {
  961. ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
  962. return -1;
  963. }
  964. return group->meth->point_cmp(group, a, b, ctx);
  965. }
  966. int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
  967. {
  968. if (group->meth->make_affine == 0) {
  969. ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  970. return 0;
  971. }
  972. if (group->meth != point->meth) {
  973. ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
  974. return 0;
  975. }
  976. return group->meth->make_affine(group, point, ctx);
  977. }
  978. int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
  979. EC_POINT *points[], BN_CTX *ctx)
  980. {
  981. size_t i;
  982. if (group->meth->points_make_affine == 0) {
  983. ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  984. return 0;
  985. }
  986. for (i = 0; i < num; i++) {
  987. if (group->meth != points[i]->meth) {
  988. ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
  989. return 0;
  990. }
  991. }
  992. return group->meth->points_make_affine(group, num, points, ctx);
  993. }
  994. /*
  995. * Functions for point multiplication. If group->meth->mul is 0, we use the
  996. * wNAF-based implementations in ec_mult.c; otherwise we dispatch through
  997. * methods.
  998. */
  999. int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
  1000. size_t num, const EC_POINT *points[],
  1001. const BIGNUM *scalars[], BN_CTX *ctx)
  1002. {
  1003. if (group->meth->mul == 0)
  1004. /* use default */
  1005. return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
  1006. return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
  1007. }
  1008. int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
  1009. const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
  1010. {
  1011. /* just a convenient interface to EC_POINTs_mul() */
  1012. const EC_POINT *points[1];
  1013. const BIGNUM *scalars[1];
  1014. points[0] = point;
  1015. scalars[0] = p_scalar;
  1016. return EC_POINTs_mul(group, r, g_scalar,
  1017. (point != NULL
  1018. && p_scalar != NULL), points, scalars, ctx);
  1019. }
  1020. int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
  1021. {
  1022. if (group->meth->mul == 0)
  1023. /* use default */
  1024. return ec_wNAF_precompute_mult(group, ctx);
  1025. if (group->meth->precompute_mult != 0)
  1026. return group->meth->precompute_mult(group, ctx);
  1027. else
  1028. return 1; /* nothing to do, so report success */
  1029. }
  1030. int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
  1031. {
  1032. if (group->meth->mul == 0)
  1033. /* use default */
  1034. return ec_wNAF_have_precompute_mult(group);
  1035. if (group->meth->have_precompute_mult != 0)
  1036. return group->meth->have_precompute_mult(group);
  1037. else
  1038. return 0; /* cannot tell whether precomputation has
  1039. * been performed */
  1040. }
  1041. /*-
  1042. * ec_precompute_mont_data sets |group->mont_data| from |group->order| and
  1043. * returns one on success. On error it returns zero.
  1044. *
  1045. * Note: this function must be called only after verifying that
  1046. * EC_GROUP_VERSION(group) returns true.
  1047. * The reason for this is that access to the `mont_data` field of an EC_GROUP
  1048. * struct should always be guarded by an EC_GROUP_VERSION(group) check to avoid
  1049. * OOB accesses, as the group might come from the FIPS module, which does not
  1050. * define the `mont_data` field inside the EC_GROUP structure.
  1051. */
  1052. static
  1053. int ec_precompute_mont_data(EC_GROUP *group)
  1054. {
  1055. BN_CTX *ctx = BN_CTX_new();
  1056. int ret = 0;
  1057. if (group->mont_data) {
  1058. BN_MONT_CTX_free(group->mont_data);
  1059. group->mont_data = NULL;
  1060. }
  1061. if (ctx == NULL)
  1062. goto err;
  1063. group->mont_data = BN_MONT_CTX_new();
  1064. if (!group->mont_data)
  1065. goto err;
  1066. if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx)) {
  1067. BN_MONT_CTX_free(group->mont_data);
  1068. group->mont_data = NULL;
  1069. goto err;
  1070. }
  1071. ret = 1;
  1072. err:
  1073. if (ctx)
  1074. BN_CTX_free(ctx);
  1075. return ret;
  1076. }
  1077. /*
  1078. * This is just a wrapper around the public functions
  1079. * - EC_GROUP_get_curve_GF2m
  1080. * - EC_GROUP_get_curve_GFp
  1081. *
  1082. * It is meant to facilitate backporting of code from newer branches, where
  1083. * the public API includes a "field agnostic" version of it.
  1084. */
  1085. int ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
  1086. BIGNUM *b, BN_CTX *ctx)
  1087. {
  1088. int field_nid;
  1089. field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
  1090. #ifndef OPENSSL_NO_EC2M
  1091. if (field_nid == NID_X9_62_characteristic_two_field) {
  1092. return EC_GROUP_get_curve_GF2m(group, p, a, b, ctx);
  1093. } else
  1094. #endif /* !def(OPENSSL_NO_EC2M) */
  1095. if (field_nid == NID_X9_62_prime_field) {
  1096. return EC_GROUP_get_curve_GFp(group, p, a, b, ctx);
  1097. } else {
  1098. /* this should never happen */
  1099. return 0;
  1100. }
  1101. }
  1102. /*
  1103. * This is just a wrapper around the public functions
  1104. * - EC_POINT_get_affine_coordinates_GF2m
  1105. * - EC_POINT_get_affine_coordinates_GFp
  1106. *
  1107. * It is meant to facilitate backporting of code from newer branches, where
  1108. * the public API includes a "field agnostic" version of it.
  1109. */
  1110. int ec_point_get_affine_coordinates(const EC_GROUP *group,
  1111. const EC_POINT *point, BIGNUM *x,
  1112. BIGNUM *y, BN_CTX *ctx)
  1113. {
  1114. int field_nid;
  1115. field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
  1116. #ifndef OPENSSL_NO_EC2M
  1117. if (field_nid == NID_X9_62_characteristic_two_field) {
  1118. return EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx);
  1119. } else
  1120. #endif /* !def(OPENSSL_NO_EC2M) */
  1121. if (field_nid == NID_X9_62_prime_field) {
  1122. return EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx);
  1123. } else {
  1124. /* this should never happen */
  1125. return 0;
  1126. }
  1127. }