ecdsa_ossl.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <string.h>
  10. #include <openssl/err.h>
  11. #include <openssl/obj_mac.h>
  12. #include <openssl/rand.h>
  13. #include "internal/bn_int.h"
  14. #include "ec_lcl.h"
  15. int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
  16. unsigned char *sig, unsigned int *siglen,
  17. const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
  18. {
  19. ECDSA_SIG *s;
  20. s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
  21. if (s == NULL) {
  22. *siglen = 0;
  23. return 0;
  24. }
  25. *siglen = i2d_ECDSA_SIG(s, &sig);
  26. ECDSA_SIG_free(s);
  27. return 1;
  28. }
  29. static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
  30. BIGNUM **kinvp, BIGNUM **rp,
  31. const unsigned char *dgst, int dlen)
  32. {
  33. BN_CTX *ctx = NULL;
  34. BIGNUM *k = NULL, *r = NULL, *X = NULL;
  35. const BIGNUM *order;
  36. EC_POINT *tmp_point = NULL;
  37. const EC_GROUP *group;
  38. int ret = 0;
  39. int order_bits;
  40. if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
  41. ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
  42. return 0;
  43. }
  44. if (!EC_KEY_can_sign(eckey)) {
  45. ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
  46. return 0;
  47. }
  48. if ((ctx = ctx_in) == NULL) {
  49. if ((ctx = BN_CTX_new()) == NULL) {
  50. ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
  51. return 0;
  52. }
  53. }
  54. k = BN_new(); /* this value is later returned in *kinvp */
  55. r = BN_new(); /* this value is later returned in *rp */
  56. X = BN_new();
  57. if (k == NULL || r == NULL || X == NULL) {
  58. ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
  59. goto err;
  60. }
  61. if ((tmp_point = EC_POINT_new(group)) == NULL) {
  62. ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
  63. goto err;
  64. }
  65. order = EC_GROUP_get0_order(group);
  66. /* Preallocate space */
  67. order_bits = BN_num_bits(order);
  68. if (!BN_set_bit(k, order_bits)
  69. || !BN_set_bit(r, order_bits)
  70. || !BN_set_bit(X, order_bits))
  71. goto err;
  72. do {
  73. /* get random k */
  74. do {
  75. if (dgst != NULL) {
  76. if (!BN_generate_dsa_nonce(k, order,
  77. EC_KEY_get0_private_key(eckey),
  78. dgst, dlen, ctx)) {
  79. ECerr(EC_F_ECDSA_SIGN_SETUP,
  80. EC_R_RANDOM_NUMBER_GENERATION_FAILED);
  81. goto err;
  82. }
  83. } else {
  84. if (!BN_priv_rand_range(k, order)) {
  85. ECerr(EC_F_ECDSA_SIGN_SETUP,
  86. EC_R_RANDOM_NUMBER_GENERATION_FAILED);
  87. goto err;
  88. }
  89. }
  90. } while (BN_is_zero(k));
  91. /* compute r the x-coordinate of generator * k */
  92. if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
  93. ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
  94. goto err;
  95. }
  96. if (!EC_POINT_get_affine_coordinates(group, tmp_point, X, NULL, ctx)) {
  97. ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
  98. goto err;
  99. }
  100. if (!BN_nnmod(r, X, order, ctx)) {
  101. ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
  102. goto err;
  103. }
  104. } while (BN_is_zero(r));
  105. /* compute the inverse of k */
  106. if (!ec_group_do_inverse_ord(group, k, k, ctx)) {
  107. ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
  108. goto err;
  109. }
  110. /* clear old values if necessary */
  111. BN_clear_free(*rp);
  112. BN_clear_free(*kinvp);
  113. /* save the pre-computed values */
  114. *rp = r;
  115. *kinvp = k;
  116. ret = 1;
  117. err:
  118. if (!ret) {
  119. BN_clear_free(k);
  120. BN_clear_free(r);
  121. }
  122. if (ctx != ctx_in)
  123. BN_CTX_free(ctx);
  124. EC_POINT_free(tmp_point);
  125. BN_clear_free(X);
  126. return ret;
  127. }
  128. int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
  129. BIGNUM **rp)
  130. {
  131. return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0);
  132. }
  133. ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
  134. const BIGNUM *in_kinv, const BIGNUM *in_r,
  135. EC_KEY *eckey)
  136. {
  137. int ok = 0, i;
  138. BIGNUM *kinv = NULL, *s, *m = NULL;
  139. const BIGNUM *order, *ckinv;
  140. BN_CTX *ctx = NULL;
  141. const EC_GROUP *group;
  142. ECDSA_SIG *ret;
  143. const BIGNUM *priv_key;
  144. group = EC_KEY_get0_group(eckey);
  145. priv_key = EC_KEY_get0_private_key(eckey);
  146. if (group == NULL || priv_key == NULL) {
  147. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER);
  148. return NULL;
  149. }
  150. if (!EC_KEY_can_sign(eckey)) {
  151. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
  152. return NULL;
  153. }
  154. ret = ECDSA_SIG_new();
  155. if (ret == NULL) {
  156. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
  157. return NULL;
  158. }
  159. ret->r = BN_new();
  160. ret->s = BN_new();
  161. if (ret->r == NULL || ret->s == NULL) {
  162. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
  163. goto err;
  164. }
  165. s = ret->s;
  166. if ((ctx = BN_CTX_new()) == NULL
  167. || (m = BN_new()) == NULL) {
  168. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
  169. goto err;
  170. }
  171. order = EC_GROUP_get0_order(group);
  172. i = BN_num_bits(order);
  173. /*
  174. * Need to truncate digest if it is too long: first truncate whole bytes.
  175. */
  176. if (8 * dgst_len > i)
  177. dgst_len = (i + 7) / 8;
  178. if (!BN_bin2bn(dgst, dgst_len, m)) {
  179. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
  180. goto err;
  181. }
  182. /* If still too long, truncate remaining bits with a shift */
  183. if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
  184. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
  185. goto err;
  186. }
  187. do {
  188. if (in_kinv == NULL || in_r == NULL) {
  189. if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) {
  190. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_ECDSA_LIB);
  191. goto err;
  192. }
  193. ckinv = kinv;
  194. } else {
  195. ckinv = in_kinv;
  196. if (BN_copy(ret->r, in_r) == NULL) {
  197. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
  198. goto err;
  199. }
  200. }
  201. /*
  202. * With only one multiplicant being in Montgomery domain
  203. * multiplication yields real result without post-conversion.
  204. * Also note that all operations but last are performed with
  205. * zero-padded vectors. Last operation, BN_mod_mul_montgomery
  206. * below, returns user-visible value with removed zero padding.
  207. */
  208. if (!bn_to_mont_fixed_top(s, ret->r, group->mont_data, ctx)
  209. || !bn_mul_mont_fixed_top(s, s, priv_key, group->mont_data, ctx)) {
  210. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
  211. goto err;
  212. }
  213. if (!bn_mod_add_fixed_top(s, s, m, order)) {
  214. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
  215. goto err;
  216. }
  217. /*
  218. * |s| can still be larger than modulus, because |m| can be. In
  219. * such case we count on Montgomery reduction to tie it up.
  220. */
  221. if (!bn_to_mont_fixed_top(s, s, group->mont_data, ctx)
  222. || !BN_mod_mul_montgomery(s, s, ckinv, group->mont_data, ctx)) {
  223. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
  224. goto err;
  225. }
  226. if (BN_is_zero(s)) {
  227. /*
  228. * if kinv and r have been supplied by the caller, don't
  229. * generate new kinv and r values
  230. */
  231. if (in_kinv != NULL && in_r != NULL) {
  232. ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_NEED_NEW_SETUP_VALUES);
  233. goto err;
  234. }
  235. } else {
  236. /* s != 0 => we have a valid signature */
  237. break;
  238. }
  239. } while (1);
  240. ok = 1;
  241. err:
  242. if (!ok) {
  243. ECDSA_SIG_free(ret);
  244. ret = NULL;
  245. }
  246. BN_CTX_free(ctx);
  247. BN_clear_free(m);
  248. BN_clear_free(kinv);
  249. return ret;
  250. }
  251. /*-
  252. * returns
  253. * 1: correct signature
  254. * 0: incorrect signature
  255. * -1: error
  256. */
  257. int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
  258. const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
  259. {
  260. ECDSA_SIG *s;
  261. const unsigned char *p = sigbuf;
  262. unsigned char *der = NULL;
  263. int derlen = -1;
  264. int ret = -1;
  265. s = ECDSA_SIG_new();
  266. if (s == NULL)
  267. return ret;
  268. if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
  269. goto err;
  270. /* Ensure signature uses DER and doesn't have trailing garbage */
  271. derlen = i2d_ECDSA_SIG(s, &der);
  272. if (derlen != sig_len || memcmp(sigbuf, der, derlen) != 0)
  273. goto err;
  274. ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);
  275. err:
  276. OPENSSL_clear_free(der, derlen);
  277. ECDSA_SIG_free(s);
  278. return ret;
  279. }
  280. int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
  281. const ECDSA_SIG *sig, EC_KEY *eckey)
  282. {
  283. int ret = -1, i;
  284. BN_CTX *ctx;
  285. const BIGNUM *order;
  286. BIGNUM *u1, *u2, *m, *X;
  287. EC_POINT *point = NULL;
  288. const EC_GROUP *group;
  289. const EC_POINT *pub_key;
  290. /* check input values */
  291. if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
  292. (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
  293. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_MISSING_PARAMETERS);
  294. return -1;
  295. }
  296. if (!EC_KEY_can_sign(eckey)) {
  297. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
  298. return -1;
  299. }
  300. ctx = BN_CTX_new();
  301. if (ctx == NULL) {
  302. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
  303. return -1;
  304. }
  305. BN_CTX_start(ctx);
  306. u1 = BN_CTX_get(ctx);
  307. u2 = BN_CTX_get(ctx);
  308. m = BN_CTX_get(ctx);
  309. X = BN_CTX_get(ctx);
  310. if (X == NULL) {
  311. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
  312. goto err;
  313. }
  314. order = EC_GROUP_get0_order(group);
  315. if (order == NULL) {
  316. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
  317. goto err;
  318. }
  319. if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
  320. BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
  321. BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
  322. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_BAD_SIGNATURE);
  323. ret = 0; /* signature is invalid */
  324. goto err;
  325. }
  326. /* calculate tmp1 = inv(S) mod order */
  327. if (!ec_group_do_inverse_ord(group, u2, sig->s, ctx)) {
  328. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
  329. goto err;
  330. }
  331. /* digest -> m */
  332. i = BN_num_bits(order);
  333. /*
  334. * Need to truncate digest if it is too long: first truncate whole bytes.
  335. */
  336. if (8 * dgst_len > i)
  337. dgst_len = (i + 7) / 8;
  338. if (!BN_bin2bn(dgst, dgst_len, m)) {
  339. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
  340. goto err;
  341. }
  342. /* If still too long truncate remaining bits with a shift */
  343. if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
  344. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
  345. goto err;
  346. }
  347. /* u1 = m * tmp mod order */
  348. if (!BN_mod_mul(u1, m, u2, order, ctx)) {
  349. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
  350. goto err;
  351. }
  352. /* u2 = r * w mod q */
  353. if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
  354. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
  355. goto err;
  356. }
  357. if ((point = EC_POINT_new(group)) == NULL) {
  358. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
  359. goto err;
  360. }
  361. if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
  362. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
  363. goto err;
  364. }
  365. if (!EC_POINT_get_affine_coordinates(group, point, X, NULL, ctx)) {
  366. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
  367. goto err;
  368. }
  369. if (!BN_nnmod(u1, X, order, ctx)) {
  370. ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
  371. goto err;
  372. }
  373. /* if the signature is correct u1 is equal to sig->r */
  374. ret = (BN_ucmp(u1, sig->r) == 0);
  375. err:
  376. BN_CTX_end(ctx);
  377. BN_CTX_free(ctx);
  378. EC_POINT_free(point);
  379. return ret;
  380. }