ec_key.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /*
  2. * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  4. *
  5. * Licensed under the OpenSSL license (the "License"). You may not use
  6. * this file except in compliance with the License. You can obtain a copy
  7. * in the file LICENSE in the source distribution or at
  8. * https://www.openssl.org/source/license.html
  9. */
  10. #include "internal/cryptlib.h"
  11. #include <string.h>
  12. #include "ec_local.h"
  13. #include "internal/refcount.h"
  14. #include <openssl/err.h>
  15. #include <openssl/engine.h>
  16. #include "crypto/bn.h"
  17. EC_KEY *EC_KEY_new(void)
  18. {
  19. return EC_KEY_new_method(NULL);
  20. }
  21. EC_KEY *EC_KEY_new_by_curve_name(int nid)
  22. {
  23. EC_KEY *ret = EC_KEY_new();
  24. if (ret == NULL)
  25. return NULL;
  26. ret->group = EC_GROUP_new_by_curve_name(nid);
  27. if (ret->group == NULL) {
  28. EC_KEY_free(ret);
  29. return NULL;
  30. }
  31. if (ret->meth->set_group != NULL
  32. && ret->meth->set_group(ret, ret->group) == 0) {
  33. EC_KEY_free(ret);
  34. return NULL;
  35. }
  36. return ret;
  37. }
  38. void EC_KEY_free(EC_KEY *r)
  39. {
  40. int i;
  41. if (r == NULL)
  42. return;
  43. CRYPTO_DOWN_REF(&r->references, &i, r->lock);
  44. REF_PRINT_COUNT("EC_KEY", r);
  45. if (i > 0)
  46. return;
  47. REF_ASSERT_ISNT(i < 0);
  48. if (r->meth != NULL && r->meth->finish != NULL)
  49. r->meth->finish(r);
  50. #ifndef OPENSSL_NO_ENGINE
  51. ENGINE_finish(r->engine);
  52. #endif
  53. if (r->group && r->group->meth->keyfinish)
  54. r->group->meth->keyfinish(r);
  55. CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
  56. CRYPTO_THREAD_lock_free(r->lock);
  57. EC_GROUP_free(r->group);
  58. EC_POINT_free(r->pub_key);
  59. BN_clear_free(r->priv_key);
  60. OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
  61. }
  62. EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
  63. {
  64. if (dest == NULL || src == NULL) {
  65. ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
  66. return NULL;
  67. }
  68. if (src->meth != dest->meth) {
  69. if (dest->meth->finish != NULL)
  70. dest->meth->finish(dest);
  71. if (dest->group && dest->group->meth->keyfinish)
  72. dest->group->meth->keyfinish(dest);
  73. #ifndef OPENSSL_NO_ENGINE
  74. if (ENGINE_finish(dest->engine) == 0)
  75. return 0;
  76. dest->engine = NULL;
  77. #endif
  78. }
  79. /* copy the parameters */
  80. if (src->group != NULL) {
  81. const EC_METHOD *meth = EC_GROUP_method_of(src->group);
  82. /* clear the old group */
  83. EC_GROUP_free(dest->group);
  84. dest->group = EC_GROUP_new(meth);
  85. if (dest->group == NULL)
  86. return NULL;
  87. if (!EC_GROUP_copy(dest->group, src->group))
  88. return NULL;
  89. /* copy the public key */
  90. if (src->pub_key != NULL) {
  91. EC_POINT_free(dest->pub_key);
  92. dest->pub_key = EC_POINT_new(src->group);
  93. if (dest->pub_key == NULL)
  94. return NULL;
  95. if (!EC_POINT_copy(dest->pub_key, src->pub_key))
  96. return NULL;
  97. }
  98. /* copy the private key */
  99. if (src->priv_key != NULL) {
  100. if (dest->priv_key == NULL) {
  101. dest->priv_key = BN_new();
  102. if (dest->priv_key == NULL)
  103. return NULL;
  104. }
  105. if (!BN_copy(dest->priv_key, src->priv_key))
  106. return NULL;
  107. if (src->group->meth->keycopy
  108. && src->group->meth->keycopy(dest, src) == 0)
  109. return NULL;
  110. }
  111. }
  112. /* copy the rest */
  113. dest->enc_flag = src->enc_flag;
  114. dest->conv_form = src->conv_form;
  115. dest->version = src->version;
  116. dest->flags = src->flags;
  117. if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
  118. &dest->ex_data, &src->ex_data))
  119. return NULL;
  120. if (src->meth != dest->meth) {
  121. #ifndef OPENSSL_NO_ENGINE
  122. if (src->engine != NULL && ENGINE_init(src->engine) == 0)
  123. return NULL;
  124. dest->engine = src->engine;
  125. #endif
  126. dest->meth = src->meth;
  127. }
  128. if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0)
  129. return NULL;
  130. return dest;
  131. }
  132. EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
  133. {
  134. EC_KEY *ret = EC_KEY_new_method(ec_key->engine);
  135. if (ret == NULL)
  136. return NULL;
  137. if (EC_KEY_copy(ret, ec_key) == NULL) {
  138. EC_KEY_free(ret);
  139. return NULL;
  140. }
  141. return ret;
  142. }
  143. int EC_KEY_up_ref(EC_KEY *r)
  144. {
  145. int i;
  146. if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
  147. return 0;
  148. REF_PRINT_COUNT("EC_KEY", r);
  149. REF_ASSERT_ISNT(i < 2);
  150. return ((i > 1) ? 1 : 0);
  151. }
  152. ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey)
  153. {
  154. return eckey->engine;
  155. }
  156. int EC_KEY_generate_key(EC_KEY *eckey)
  157. {
  158. if (eckey == NULL || eckey->group == NULL) {
  159. ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
  160. return 0;
  161. }
  162. if (eckey->meth->keygen != NULL)
  163. return eckey->meth->keygen(eckey);
  164. ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
  165. return 0;
  166. }
  167. int ossl_ec_key_gen(EC_KEY *eckey)
  168. {
  169. return eckey->group->meth->keygen(eckey);
  170. }
  171. int ec_key_simple_generate_key(EC_KEY *eckey)
  172. {
  173. int ok = 0;
  174. BN_CTX *ctx = NULL;
  175. BIGNUM *priv_key = NULL;
  176. const BIGNUM *order = NULL;
  177. EC_POINT *pub_key = NULL;
  178. if ((ctx = BN_CTX_new()) == NULL)
  179. goto err;
  180. if (eckey->priv_key == NULL) {
  181. priv_key = BN_new();
  182. if (priv_key == NULL)
  183. goto err;
  184. } else
  185. priv_key = eckey->priv_key;
  186. order = EC_GROUP_get0_order(eckey->group);
  187. if (order == NULL)
  188. goto err;
  189. do
  190. if (!BN_priv_rand_range(priv_key, order))
  191. goto err;
  192. while (BN_is_zero(priv_key)) ;
  193. if (eckey->pub_key == NULL) {
  194. pub_key = EC_POINT_new(eckey->group);
  195. if (pub_key == NULL)
  196. goto err;
  197. } else
  198. pub_key = eckey->pub_key;
  199. if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
  200. goto err;
  201. eckey->priv_key = priv_key;
  202. eckey->pub_key = pub_key;
  203. ok = 1;
  204. err:
  205. if (eckey->pub_key == NULL)
  206. EC_POINT_free(pub_key);
  207. if (eckey->priv_key != priv_key)
  208. BN_free(priv_key);
  209. BN_CTX_free(ctx);
  210. return ok;
  211. }
  212. int ec_key_simple_generate_public_key(EC_KEY *eckey)
  213. {
  214. return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
  215. NULL, NULL);
  216. }
  217. int EC_KEY_check_key(const EC_KEY *eckey)
  218. {
  219. if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
  220. ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
  221. return 0;
  222. }
  223. if (eckey->group->meth->keycheck == NULL) {
  224. ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  225. return 0;
  226. }
  227. return eckey->group->meth->keycheck(eckey);
  228. }
  229. int ec_key_simple_check_key(const EC_KEY *eckey)
  230. {
  231. int ok = 0;
  232. BN_CTX *ctx = NULL;
  233. const BIGNUM *order = NULL;
  234. EC_POINT *point = NULL;
  235. if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
  236. ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
  237. return 0;
  238. }
  239. if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
  240. ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY);
  241. goto err;
  242. }
  243. if ((ctx = BN_CTX_new()) == NULL)
  244. goto err;
  245. if ((point = EC_POINT_new(eckey->group)) == NULL)
  246. goto err;
  247. /* testing whether the pub_key is on the elliptic curve */
  248. if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
  249. ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
  250. goto err;
  251. }
  252. /* testing whether pub_key * order is the point at infinity */
  253. order = eckey->group->order;
  254. if (BN_is_zero(order)) {
  255. ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
  256. goto err;
  257. }
  258. if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
  259. ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
  260. goto err;
  261. }
  262. if (!EC_POINT_is_at_infinity(eckey->group, point)) {
  263. ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
  264. goto err;
  265. }
  266. /*
  267. * in case the priv_key is present : check if generator * priv_key ==
  268. * pub_key
  269. */
  270. if (eckey->priv_key != NULL) {
  271. if (BN_cmp(eckey->priv_key, order) >= 0) {
  272. ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
  273. goto err;
  274. }
  275. if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
  276. NULL, NULL, ctx)) {
  277. ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
  278. goto err;
  279. }
  280. if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
  281. ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
  282. goto err;
  283. }
  284. }
  285. ok = 1;
  286. err:
  287. BN_CTX_free(ctx);
  288. EC_POINT_free(point);
  289. return ok;
  290. }
  291. int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
  292. BIGNUM *y)
  293. {
  294. BN_CTX *ctx = NULL;
  295. BIGNUM *tx, *ty;
  296. EC_POINT *point = NULL;
  297. int ok = 0;
  298. if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
  299. ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
  300. ERR_R_PASSED_NULL_PARAMETER);
  301. return 0;
  302. }
  303. ctx = BN_CTX_new();
  304. if (ctx == NULL)
  305. return 0;
  306. BN_CTX_start(ctx);
  307. point = EC_POINT_new(key->group);
  308. if (point == NULL)
  309. goto err;
  310. tx = BN_CTX_get(ctx);
  311. ty = BN_CTX_get(ctx);
  312. if (ty == NULL)
  313. goto err;
  314. if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx))
  315. goto err;
  316. if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx))
  317. goto err;
  318. /*
  319. * Check if retrieved coordinates match originals and are less than field
  320. * order: if not values are out of range.
  321. */
  322. if (BN_cmp(x, tx) || BN_cmp(y, ty)
  323. || (BN_cmp(x, key->group->field) >= 0)
  324. || (BN_cmp(y, key->group->field) >= 0)) {
  325. ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
  326. EC_R_COORDINATES_OUT_OF_RANGE);
  327. goto err;
  328. }
  329. if (!EC_KEY_set_public_key(key, point))
  330. goto err;
  331. if (EC_KEY_check_key(key) == 0)
  332. goto err;
  333. ok = 1;
  334. err:
  335. BN_CTX_end(ctx);
  336. BN_CTX_free(ctx);
  337. EC_POINT_free(point);
  338. return ok;
  339. }
  340. const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
  341. {
  342. return key->group;
  343. }
  344. int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
  345. {
  346. if (key->meth->set_group != NULL && key->meth->set_group(key, group) == 0)
  347. return 0;
  348. EC_GROUP_free(key->group);
  349. key->group = EC_GROUP_dup(group);
  350. return (key->group == NULL) ? 0 : 1;
  351. }
  352. const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
  353. {
  354. return key->priv_key;
  355. }
  356. int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
  357. {
  358. int fixed_top;
  359. const BIGNUM *order = NULL;
  360. BIGNUM *tmp_key = NULL;
  361. if (key->group == NULL || key->group->meth == NULL)
  362. return 0;
  363. /*
  364. * Not only should key->group be set, but it should also be in a valid
  365. * fully initialized state.
  366. *
  367. * Specifically, to operate in constant time, we need that the group order
  368. * is set, as we use its length as the fixed public size of any scalar used
  369. * as an EC private key.
  370. */
  371. order = EC_GROUP_get0_order(key->group);
  372. if (order == NULL || BN_is_zero(order))
  373. return 0; /* This should never happen */
  374. if (key->group->meth->set_private != NULL
  375. && key->group->meth->set_private(key, priv_key) == 0)
  376. return 0;
  377. if (key->meth->set_private != NULL
  378. && key->meth->set_private(key, priv_key) == 0)
  379. return 0;
  380. /*
  381. * Return `0` to comply with legacy behavior for this function, see
  382. * https://github.com/openssl/openssl/issues/18744#issuecomment-1195175696
  383. */
  384. if (priv_key == NULL) {
  385. BN_clear_free(key->priv_key);
  386. key->priv_key = NULL;
  387. return 0; /* intentional for legacy compatibility */
  388. }
  389. /*
  390. * We should never leak the bit length of the secret scalar in the key,
  391. * so we always set the `BN_FLG_CONSTTIME` flag on the internal `BIGNUM`
  392. * holding the secret scalar.
  393. *
  394. * This is important also because `BN_dup()` (and `BN_copy()`) do not
  395. * propagate the `BN_FLG_CONSTTIME` flag from the source `BIGNUM`, and
  396. * this brings an extra risk of inadvertently losing the flag, even when
  397. * the caller specifically set it.
  398. *
  399. * The propagation has been turned on and off a few times in the past
  400. * years because in some conditions has shown unintended consequences in
  401. * some code paths, so at the moment we can't fix this in the BN layer.
  402. *
  403. * In `EC_KEY_set_private_key()` we can work around the propagation by
  404. * manually setting the flag after `BN_dup()` as we know for sure that
  405. * inside the EC module the `BN_FLG_CONSTTIME` is always treated
  406. * correctly and should not generate unintended consequences.
  407. *
  408. * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
  409. * to preallocate the BIGNUM internal buffer to a fixed public size big
  410. * enough that operations performed during the processing never trigger
  411. * a realloc which would leak the size of the scalar through memory
  412. * accesses.
  413. *
  414. * Fixed Length
  415. * ------------
  416. *
  417. * The order of the large prime subgroup of the curve is our choice for
  418. * a fixed public size, as that is generally the upper bound for
  419. * generating a private key in EC cryptosystems and should fit all valid
  420. * secret scalars.
  421. *
  422. * For preallocating the BIGNUM storage we look at the number of "words"
  423. * required for the internal representation of the order, and we
  424. * preallocate 2 extra "words" in case any of the subsequent processing
  425. * might temporarily overflow the order length.
  426. */
  427. tmp_key = BN_dup(priv_key);
  428. if (tmp_key == NULL)
  429. return 0;
  430. BN_set_flags(tmp_key, BN_FLG_CONSTTIME);
  431. fixed_top = bn_get_top(order) + 2;
  432. if (bn_wexpand(tmp_key, fixed_top) == NULL) {
  433. BN_clear_free(tmp_key);
  434. return 0;
  435. }
  436. BN_clear_free(key->priv_key);
  437. key->priv_key = tmp_key;
  438. return 1;
  439. }
  440. const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
  441. {
  442. return key->pub_key;
  443. }
  444. int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
  445. {
  446. if (key->meth->set_public != NULL
  447. && key->meth->set_public(key, pub_key) == 0)
  448. return 0;
  449. EC_POINT_free(key->pub_key);
  450. key->pub_key = EC_POINT_dup(pub_key, key->group);
  451. return (key->pub_key == NULL) ? 0 : 1;
  452. }
  453. unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
  454. {
  455. return key->enc_flag;
  456. }
  457. void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
  458. {
  459. key->enc_flag = flags;
  460. }
  461. point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
  462. {
  463. return key->conv_form;
  464. }
  465. void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
  466. {
  467. key->conv_form = cform;
  468. if (key->group != NULL)
  469. EC_GROUP_set_point_conversion_form(key->group, cform);
  470. }
  471. void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
  472. {
  473. if (key->group != NULL)
  474. EC_GROUP_set_asn1_flag(key->group, flag);
  475. }
  476. int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
  477. {
  478. if (key->group == NULL)
  479. return 0;
  480. return EC_GROUP_precompute_mult(key->group, ctx);
  481. }
  482. int EC_KEY_get_flags(const EC_KEY *key)
  483. {
  484. return key->flags;
  485. }
  486. void EC_KEY_set_flags(EC_KEY *key, int flags)
  487. {
  488. key->flags |= flags;
  489. }
  490. void EC_KEY_clear_flags(EC_KEY *key, int flags)
  491. {
  492. key->flags &= ~flags;
  493. }
  494. int EC_KEY_decoded_from_explicit_params(const EC_KEY *key)
  495. {
  496. if (key == NULL || key->group == NULL)
  497. return -1;
  498. return key->group->decoded_from_explicit_params;
  499. }
  500. size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
  501. unsigned char **pbuf, BN_CTX *ctx)
  502. {
  503. if (key == NULL || key->pub_key == NULL || key->group == NULL)
  504. return 0;
  505. return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx);
  506. }
  507. int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
  508. BN_CTX *ctx)
  509. {
  510. if (key == NULL || key->group == NULL)
  511. return 0;
  512. if (key->pub_key == NULL)
  513. key->pub_key = EC_POINT_new(key->group);
  514. if (key->pub_key == NULL)
  515. return 0;
  516. if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0)
  517. return 0;
  518. /*
  519. * Save the point conversion form.
  520. * For non-custom curves the first octet of the buffer (excluding
  521. * the last significant bit) contains the point conversion form.
  522. * EC_POINT_oct2point() has already performed sanity checking of
  523. * the buffer so we know it is valid.
  524. */
  525. if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0)
  526. key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01);
  527. return 1;
  528. }
  529. size_t EC_KEY_priv2oct(const EC_KEY *eckey,
  530. unsigned char *buf, size_t len)
  531. {
  532. if (eckey->group == NULL || eckey->group->meth == NULL)
  533. return 0;
  534. if (eckey->group->meth->priv2oct == NULL) {
  535. ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  536. return 0;
  537. }
  538. return eckey->group->meth->priv2oct(eckey, buf, len);
  539. }
  540. size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
  541. unsigned char *buf, size_t len)
  542. {
  543. size_t buf_len;
  544. buf_len = (EC_GROUP_order_bits(eckey->group) + 7) / 8;
  545. if (eckey->priv_key == NULL)
  546. return 0;
  547. if (buf == NULL)
  548. return buf_len;
  549. else if (len < buf_len)
  550. return 0;
  551. /* Octetstring may need leading zeros if BN is to short */
  552. if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) {
  553. ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL);
  554. return 0;
  555. }
  556. return buf_len;
  557. }
  558. int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
  559. {
  560. if (eckey->group == NULL || eckey->group->meth == NULL)
  561. return 0;
  562. if (eckey->group->meth->oct2priv == NULL) {
  563. ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  564. return 0;
  565. }
  566. return eckey->group->meth->oct2priv(eckey, buf, len);
  567. }
  568. int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
  569. {
  570. if (eckey->priv_key == NULL)
  571. eckey->priv_key = BN_secure_new();
  572. if (eckey->priv_key == NULL) {
  573. ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE);
  574. return 0;
  575. }
  576. if (BN_bin2bn(buf, len, eckey->priv_key) == NULL) {
  577. ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB);
  578. return 0;
  579. }
  580. return 1;
  581. }
  582. size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
  583. {
  584. size_t len;
  585. unsigned char *buf;
  586. len = EC_KEY_priv2oct(eckey, NULL, 0);
  587. if (len == 0)
  588. return 0;
  589. if ((buf = OPENSSL_malloc(len)) == NULL) {
  590. ECerr(EC_F_EC_KEY_PRIV2BUF, ERR_R_MALLOC_FAILURE);
  591. return 0;
  592. }
  593. len = EC_KEY_priv2oct(eckey, buf, len);
  594. if (len == 0) {
  595. OPENSSL_free(buf);
  596. return 0;
  597. }
  598. *pbuf = buf;
  599. return len;
  600. }
  601. int EC_KEY_can_sign(const EC_KEY *eckey)
  602. {
  603. if (eckey->group == NULL || eckey->group->meth == NULL
  604. || (eckey->group->meth->flags & EC_FLAGS_NO_SIGN))
  605. return 0;
  606. return 1;
  607. }