ecs_ossl.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. /* crypto/ecdsa/ecs_ossl.c */
  2. /*
  3. * Written by Nils Larsch for the OpenSSL project
  4. */
  5. /* ====================================================================
  6. * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. All advertising materials mentioning features or use of this
  21. * software must display the following acknowledgment:
  22. * "This product includes software developed by the OpenSSL Project
  23. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24. *
  25. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26. * endorse or promote products derived from this software without
  27. * prior written permission. For written permission, please contact
  28. * openssl-core@OpenSSL.org.
  29. *
  30. * 5. Products derived from this software may not be called "OpenSSL"
  31. * nor may "OpenSSL" appear in their names without prior written
  32. * permission of the OpenSSL Project.
  33. *
  34. * 6. Redistributions of any form whatsoever must retain the following
  35. * acknowledgment:
  36. * "This product includes software developed by the OpenSSL Project
  37. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38. *
  39. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50. * OF THE POSSIBILITY OF SUCH DAMAGE.
  51. * ====================================================================
  52. *
  53. * This product includes cryptographic software written by Eric Young
  54. * (eay@cryptsoft.com). This product includes software written by Tim
  55. * Hudson (tjh@cryptsoft.com).
  56. *
  57. */
  58. #define OPENSSL_FIPSAPI
  59. #include "ecs_locl.h"
  60. #include <openssl/err.h>
  61. #include <openssl/obj_mac.h>
  62. #include <openssl/bn.h>
  63. static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
  64. const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
  65. static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
  66. BIGNUM **rp);
  67. static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
  68. const ECDSA_SIG *sig, EC_KEY *eckey);
  69. static ECDSA_METHOD openssl_ecdsa_meth = {
  70. "OpenSSL ECDSA method",
  71. ecdsa_do_sign,
  72. ecdsa_sign_setup,
  73. ecdsa_do_verify,
  74. #if 0
  75. NULL, /* init */
  76. NULL, /* finish */
  77. #endif
  78. ECDSA_FLAG_FIPS_METHOD, /* flags */
  79. NULL /* app_data */
  80. };
  81. const ECDSA_METHOD *ECDSA_OpenSSL(void)
  82. {
  83. return &openssl_ecdsa_meth;
  84. }
  85. static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
  86. BIGNUM **rp)
  87. {
  88. BN_CTX *ctx = NULL;
  89. BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
  90. EC_POINT *tmp_point=NULL;
  91. const EC_GROUP *group;
  92. int ret = 0;
  93. if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
  94. {
  95. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
  96. return 0;
  97. }
  98. if (ctx_in == NULL)
  99. {
  100. if ((ctx = BN_CTX_new()) == NULL)
  101. {
  102. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
  103. return 0;
  104. }
  105. }
  106. else
  107. ctx = ctx_in;
  108. k = BN_new(); /* this value is later returned in *kinvp */
  109. r = BN_new(); /* this value is later returned in *rp */
  110. order = BN_new();
  111. X = BN_new();
  112. if (!k || !r || !order || !X)
  113. {
  114. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
  115. goto err;
  116. }
  117. if ((tmp_point = EC_POINT_new(group)) == NULL)
  118. {
  119. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
  120. goto err;
  121. }
  122. if (!EC_GROUP_get_order(group, order, ctx))
  123. {
  124. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
  125. goto err;
  126. }
  127. #ifdef OPENSSL_FIPS
  128. if (!fips_check_ec_prng(eckey))
  129. goto err;
  130. #endif
  131. do
  132. {
  133. /* get random k */
  134. do
  135. if (!BN_rand_range(k, order))
  136. {
  137. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
  138. ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
  139. goto err;
  140. }
  141. while (BN_is_zero(k));
  142. /* We do not want timing information to leak the length of k,
  143. * so we compute G*k using an equivalent scalar of fixed
  144. * bit-length. */
  145. if (!BN_add(k, k, order)) goto err;
  146. if (BN_num_bits(k) <= BN_num_bits(order))
  147. if (!BN_add(k, k, order)) goto err;
  148. /* compute r the x-coordinate of generator * k */
  149. if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
  150. {
  151. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
  152. goto err;
  153. }
  154. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  155. {
  156. if (!EC_POINT_get_affine_coordinates_GFp(group,
  157. tmp_point, X, NULL, ctx))
  158. {
  159. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
  160. goto err;
  161. }
  162. }
  163. #ifndef OPENSSL_NO_EC2M
  164. else /* NID_X9_62_characteristic_two_field */
  165. {
  166. if (!EC_POINT_get_affine_coordinates_GF2m(group,
  167. tmp_point, X, NULL, ctx))
  168. {
  169. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
  170. goto err;
  171. }
  172. }
  173. #endif
  174. if (!BN_nnmod(r, X, order, ctx))
  175. {
  176. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
  177. goto err;
  178. }
  179. }
  180. while (BN_is_zero(r));
  181. /* compute the inverse of k */
  182. if (!BN_mod_inverse(k, k, order, ctx))
  183. {
  184. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
  185. goto err;
  186. }
  187. /* clear old values if necessary */
  188. if (*rp != NULL)
  189. BN_clear_free(*rp);
  190. if (*kinvp != NULL)
  191. BN_clear_free(*kinvp);
  192. /* save the pre-computed values */
  193. *rp = r;
  194. *kinvp = k;
  195. ret = 1;
  196. err:
  197. if (!ret)
  198. {
  199. if (k != NULL) BN_clear_free(k);
  200. if (r != NULL) BN_clear_free(r);
  201. }
  202. if (ctx_in == NULL)
  203. BN_CTX_free(ctx);
  204. if (order != NULL)
  205. BN_free(order);
  206. if (tmp_point != NULL)
  207. EC_POINT_free(tmp_point);
  208. if (X)
  209. BN_clear_free(X);
  210. return(ret);
  211. }
  212. static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
  213. const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
  214. {
  215. int ok = 0, i;
  216. BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
  217. const BIGNUM *ckinv;
  218. BN_CTX *ctx = NULL;
  219. const EC_GROUP *group;
  220. ECDSA_SIG *ret;
  221. ECDSA_DATA *ecdsa;
  222. const BIGNUM *priv_key;
  223. ecdsa = ecdsa_check(eckey);
  224. group = EC_KEY_get0_group(eckey);
  225. priv_key = EC_KEY_get0_private_key(eckey);
  226. if (group == NULL || priv_key == NULL || ecdsa == NULL)
  227. {
  228. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
  229. return NULL;
  230. }
  231. #ifdef OPENSSL_FIPS
  232. if (!fips_check_ec_prng(eckey))
  233. return NULL;
  234. #endif
  235. ret = ECDSA_SIG_new();
  236. if (!ret)
  237. {
  238. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
  239. return NULL;
  240. }
  241. s = ret->s;
  242. if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
  243. (tmp = BN_new()) == NULL || (m = BN_new()) == NULL)
  244. {
  245. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
  246. goto err;
  247. }
  248. if (!EC_GROUP_get_order(group, order, ctx))
  249. {
  250. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
  251. goto err;
  252. }
  253. i = BN_num_bits(order);
  254. /* Need to truncate digest if it is too long: first truncate whole
  255. * bytes.
  256. */
  257. if (8 * dgst_len > i)
  258. dgst_len = (i + 7)/8;
  259. if (!BN_bin2bn(dgst, dgst_len, m))
  260. {
  261. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  262. goto err;
  263. }
  264. /* If still too long truncate remaining bits with a shift */
  265. if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
  266. {
  267. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  268. goto err;
  269. }
  270. do
  271. {
  272. if (in_kinv == NULL || in_r == NULL)
  273. {
  274. if (!ecdsa->meth->ecdsa_sign_setup(eckey, ctx,
  275. &kinv, &ret->r))
  276. {
  277. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
  278. goto err;
  279. }
  280. ckinv = kinv;
  281. }
  282. else
  283. {
  284. ckinv = in_kinv;
  285. if (BN_copy(ret->r, in_r) == NULL)
  286. {
  287. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
  288. goto err;
  289. }
  290. }
  291. if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
  292. {
  293. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  294. goto err;
  295. }
  296. if (!BN_mod_add_quick(s, tmp, m, order))
  297. {
  298. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  299. goto err;
  300. }
  301. if (!BN_mod_mul(s, s, ckinv, order, ctx))
  302. {
  303. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  304. goto err;
  305. }
  306. if (BN_is_zero(s))
  307. {
  308. /* if kinv and r have been supplied by the caller
  309. * don't to generate new kinv and r values */
  310. if (in_kinv != NULL && in_r != NULL)
  311. {
  312. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
  313. goto err;
  314. }
  315. }
  316. else
  317. /* s != 0 => we have a valid signature */
  318. break;
  319. }
  320. while (1);
  321. ok = 1;
  322. err:
  323. if (!ok)
  324. {
  325. ECDSA_SIG_free(ret);
  326. ret = NULL;
  327. }
  328. if (ctx)
  329. BN_CTX_free(ctx);
  330. if (m)
  331. BN_clear_free(m);
  332. if (tmp)
  333. BN_clear_free(tmp);
  334. if (order)
  335. BN_free(order);
  336. if (kinv)
  337. BN_clear_free(kinv);
  338. return ret;
  339. }
  340. static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
  341. const ECDSA_SIG *sig, EC_KEY *eckey)
  342. {
  343. int ret = -1, i;
  344. BN_CTX *ctx;
  345. BIGNUM *order, *u1, *u2, *m, *X;
  346. EC_POINT *point = NULL;
  347. const EC_GROUP *group;
  348. const EC_POINT *pub_key;
  349. /* check input values */
  350. if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
  351. (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
  352. {
  353. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
  354. return -1;
  355. }
  356. ctx = BN_CTX_new();
  357. if (!ctx)
  358. {
  359. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
  360. return -1;
  361. }
  362. BN_CTX_start(ctx);
  363. order = BN_CTX_get(ctx);
  364. u1 = BN_CTX_get(ctx);
  365. u2 = BN_CTX_get(ctx);
  366. m = BN_CTX_get(ctx);
  367. X = BN_CTX_get(ctx);
  368. if (!X)
  369. {
  370. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  371. goto err;
  372. }
  373. if (!EC_GROUP_get_order(group, order, ctx))
  374. {
  375. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
  376. goto err;
  377. }
  378. if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
  379. BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
  380. BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0)
  381. {
  382. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
  383. ret = 0; /* signature is invalid */
  384. goto err;
  385. }
  386. /* calculate tmp1 = inv(S) mod order */
  387. if (!BN_mod_inverse(u2, sig->s, order, ctx))
  388. {
  389. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  390. goto err;
  391. }
  392. /* digest -> m */
  393. i = BN_num_bits(order);
  394. /* Need to truncate digest if it is too long: first truncate whole
  395. * bytes.
  396. */
  397. if (8 * dgst_len > i)
  398. dgst_len = (i + 7)/8;
  399. if (!BN_bin2bn(dgst, dgst_len, m))
  400. {
  401. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  402. goto err;
  403. }
  404. /* If still too long truncate remaining bits with a shift */
  405. if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
  406. {
  407. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  408. goto err;
  409. }
  410. /* u1 = m * tmp mod order */
  411. if (!BN_mod_mul(u1, m, u2, order, ctx))
  412. {
  413. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  414. goto err;
  415. }
  416. /* u2 = r * w mod q */
  417. if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
  418. {
  419. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  420. goto err;
  421. }
  422. if ((point = EC_POINT_new(group)) == NULL)
  423. {
  424. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
  425. goto err;
  426. }
  427. if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
  428. {
  429. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
  430. goto err;
  431. }
  432. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  433. {
  434. if (!EC_POINT_get_affine_coordinates_GFp(group,
  435. point, X, NULL, ctx))
  436. {
  437. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
  438. goto err;
  439. }
  440. }
  441. #ifndef OPENSSL_NO_EC2M
  442. else /* NID_X9_62_characteristic_two_field */
  443. {
  444. if (!EC_POINT_get_affine_coordinates_GF2m(group,
  445. point, X, NULL, ctx))
  446. {
  447. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
  448. goto err;
  449. }
  450. }
  451. #endif
  452. if (!BN_nnmod(u1, X, order, ctx))
  453. {
  454. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  455. goto err;
  456. }
  457. /* if the signature is correct u1 is equal to sig->r */
  458. ret = (BN_ucmp(u1, sig->r) == 0);
  459. err:
  460. BN_CTX_end(ctx);
  461. BN_CTX_free(ctx);
  462. if (point)
  463. EC_POINT_free(point);
  464. return ret;
  465. }
  466. #ifdef OPENSSL_FIPSCANISTER
  467. /* FIPS stanadlone version of ecdsa_check: just return FIPS method */
  468. ECDSA_DATA *fips_ecdsa_check(EC_KEY *key)
  469. {
  470. static ECDSA_DATA rv = {
  471. 0,0,0,
  472. &openssl_ecdsa_meth
  473. };
  474. return &rv;
  475. }
  476. /* Standalone digest sign and verify */
  477. int FIPS_ecdsa_verify_digest(EC_KEY *key,
  478. const unsigned char *dig, int dlen, ECDSA_SIG *s)
  479. {
  480. ECDSA_DATA *ecdsa = ecdsa_check(key);
  481. if (ecdsa == NULL)
  482. return 0;
  483. return ecdsa->meth->ecdsa_do_verify(dig, dlen, s, key);
  484. }
  485. ECDSA_SIG * FIPS_ecdsa_sign_digest(EC_KEY *key,
  486. const unsigned char *dig, int dlen)
  487. {
  488. ECDSA_DATA *ecdsa = ecdsa_check(key);
  489. if (ecdsa == NULL)
  490. return NULL;
  491. return ecdsa->meth->ecdsa_do_sign(dig, dlen, NULL, NULL, key);
  492. }
  493. #endif