ecp_oct.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*
  2. * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  4. *
  5. * Licensed under the Apache License 2.0 (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. /*
  11. * ECDSA low level APIs are deprecated for public use, but still ok for
  12. * internal use.
  13. */
  14. #include "internal/deprecated.h"
  15. #include <openssl/err.h>
  16. #include <openssl/symhacks.h>
  17. #include "ec_local.h"
  18. int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
  19. EC_POINT *point,
  20. const BIGNUM *x_, int y_bit,
  21. BN_CTX *ctx)
  22. {
  23. BN_CTX *new_ctx = NULL;
  24. BIGNUM *tmp1, *tmp2, *x, *y;
  25. int ret = 0;
  26. #ifndef FIPS_MODE
  27. /* clear error queue */
  28. ERR_clear_error();
  29. #endif
  30. if (ctx == NULL) {
  31. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  32. if (ctx == NULL)
  33. return 0;
  34. }
  35. y_bit = (y_bit != 0);
  36. BN_CTX_start(ctx);
  37. tmp1 = BN_CTX_get(ctx);
  38. tmp2 = BN_CTX_get(ctx);
  39. x = BN_CTX_get(ctx);
  40. y = BN_CTX_get(ctx);
  41. if (y == NULL)
  42. goto err;
  43. /*-
  44. * Recover y. We have a Weierstrass equation
  45. * y^2 = x^3 + a*x + b,
  46. * so y is one of the square roots of x^3 + a*x + b.
  47. */
  48. /* tmp1 := x^3 */
  49. if (!BN_nnmod(x, x_, group->field, ctx))
  50. goto err;
  51. if (group->meth->field_decode == 0) {
  52. /* field_{sqr,mul} work on standard representation */
  53. if (!group->meth->field_sqr(group, tmp2, x_, ctx))
  54. goto err;
  55. if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
  56. goto err;
  57. } else {
  58. if (!BN_mod_sqr(tmp2, x_, group->field, ctx))
  59. goto err;
  60. if (!BN_mod_mul(tmp1, tmp2, x_, group->field, ctx))
  61. goto err;
  62. }
  63. /* tmp1 := tmp1 + a*x */
  64. if (group->a_is_minus3) {
  65. if (!BN_mod_lshift1_quick(tmp2, x, group->field))
  66. goto err;
  67. if (!BN_mod_add_quick(tmp2, tmp2, x, group->field))
  68. goto err;
  69. if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, group->field))
  70. goto err;
  71. } else {
  72. if (group->meth->field_decode) {
  73. if (!group->meth->field_decode(group, tmp2, group->a, ctx))
  74. goto err;
  75. if (!BN_mod_mul(tmp2, tmp2, x, group->field, ctx))
  76. goto err;
  77. } else {
  78. /* field_mul works on standard representation */
  79. if (!group->meth->field_mul(group, tmp2, group->a, x, ctx))
  80. goto err;
  81. }
  82. if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field))
  83. goto err;
  84. }
  85. /* tmp1 := tmp1 + b */
  86. if (group->meth->field_decode) {
  87. if (!group->meth->field_decode(group, tmp2, group->b, ctx))
  88. goto err;
  89. if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field))
  90. goto err;
  91. } else {
  92. if (!BN_mod_add_quick(tmp1, tmp1, group->b, group->field))
  93. goto err;
  94. }
  95. if (!BN_mod_sqrt(y, tmp1, group->field, ctx)) {
  96. #ifndef FIPS_MODE
  97. unsigned long err = ERR_peek_last_error();
  98. if (ERR_GET_LIB(err) == ERR_LIB_BN
  99. && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
  100. ERR_clear_error();
  101. ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
  102. EC_R_INVALID_COMPRESSED_POINT);
  103. } else
  104. #endif
  105. {
  106. ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
  107. ERR_R_BN_LIB);
  108. }
  109. goto err;
  110. }
  111. if (y_bit != BN_is_odd(y)) {
  112. if (BN_is_zero(y)) {
  113. int kron;
  114. kron = BN_kronecker(x, group->field, ctx);
  115. if (kron == -2)
  116. goto err;
  117. if (kron == 1)
  118. ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
  119. EC_R_INVALID_COMPRESSION_BIT);
  120. else
  121. /*
  122. * BN_mod_sqrt() should have caught this error (not a square)
  123. */
  124. ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
  125. EC_R_INVALID_COMPRESSED_POINT);
  126. goto err;
  127. }
  128. if (!BN_usub(y, group->field, y))
  129. goto err;
  130. }
  131. if (y_bit != BN_is_odd(y)) {
  132. ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
  133. ERR_R_INTERNAL_ERROR);
  134. goto err;
  135. }
  136. if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
  137. goto err;
  138. ret = 1;
  139. err:
  140. BN_CTX_end(ctx);
  141. BN_CTX_free(new_ctx);
  142. return ret;
  143. }
  144. size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
  145. point_conversion_form_t form,
  146. unsigned char *buf, size_t len, BN_CTX *ctx)
  147. {
  148. size_t ret;
  149. BN_CTX *new_ctx = NULL;
  150. int used_ctx = 0;
  151. BIGNUM *x, *y;
  152. size_t field_len, i, skip;
  153. if ((form != POINT_CONVERSION_COMPRESSED)
  154. && (form != POINT_CONVERSION_UNCOMPRESSED)
  155. && (form != POINT_CONVERSION_HYBRID)) {
  156. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
  157. goto err;
  158. }
  159. if (EC_POINT_is_at_infinity(group, point)) {
  160. /* encodes to a single 0 octet */
  161. if (buf != NULL) {
  162. if (len < 1) {
  163. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
  164. return 0;
  165. }
  166. buf[0] = 0;
  167. }
  168. return 1;
  169. }
  170. /* ret := required output buffer length */
  171. field_len = BN_num_bytes(group->field);
  172. ret =
  173. (form ==
  174. POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
  175. /* if 'buf' is NULL, just return required length */
  176. if (buf != NULL) {
  177. if (len < ret) {
  178. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
  179. goto err;
  180. }
  181. if (ctx == NULL) {
  182. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  183. if (ctx == NULL)
  184. return 0;
  185. }
  186. BN_CTX_start(ctx);
  187. used_ctx = 1;
  188. x = BN_CTX_get(ctx);
  189. y = BN_CTX_get(ctx);
  190. if (y == NULL)
  191. goto err;
  192. if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
  193. goto err;
  194. if ((form == POINT_CONVERSION_COMPRESSED
  195. || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
  196. buf[0] = form + 1;
  197. else
  198. buf[0] = form;
  199. i = 1;
  200. skip = field_len - BN_num_bytes(x);
  201. if (skip > field_len) {
  202. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
  203. goto err;
  204. }
  205. while (skip > 0) {
  206. buf[i++] = 0;
  207. skip--;
  208. }
  209. skip = BN_bn2bin(x, buf + i);
  210. i += skip;
  211. if (i != 1 + field_len) {
  212. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
  213. goto err;
  214. }
  215. if (form == POINT_CONVERSION_UNCOMPRESSED
  216. || form == POINT_CONVERSION_HYBRID) {
  217. skip = field_len - BN_num_bytes(y);
  218. if (skip > field_len) {
  219. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
  220. goto err;
  221. }
  222. while (skip > 0) {
  223. buf[i++] = 0;
  224. skip--;
  225. }
  226. skip = BN_bn2bin(y, buf + i);
  227. i += skip;
  228. }
  229. if (i != ret) {
  230. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
  231. goto err;
  232. }
  233. }
  234. if (used_ctx)
  235. BN_CTX_end(ctx);
  236. BN_CTX_free(new_ctx);
  237. return ret;
  238. err:
  239. if (used_ctx)
  240. BN_CTX_end(ctx);
  241. BN_CTX_free(new_ctx);
  242. return 0;
  243. }
  244. int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
  245. const unsigned char *buf, size_t len, BN_CTX *ctx)
  246. {
  247. point_conversion_form_t form;
  248. int y_bit;
  249. BN_CTX *new_ctx = NULL;
  250. BIGNUM *x, *y;
  251. size_t field_len, enc_len;
  252. int ret = 0;
  253. if (len == 0) {
  254. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
  255. return 0;
  256. }
  257. form = buf[0];
  258. y_bit = form & 1;
  259. form = form & ~1U;
  260. if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
  261. && (form != POINT_CONVERSION_UNCOMPRESSED)
  262. && (form != POINT_CONVERSION_HYBRID)) {
  263. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  264. return 0;
  265. }
  266. if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
  267. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  268. return 0;
  269. }
  270. if (form == 0) {
  271. if (len != 1) {
  272. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  273. return 0;
  274. }
  275. return EC_POINT_set_to_infinity(group, point);
  276. }
  277. field_len = BN_num_bytes(group->field);
  278. enc_len =
  279. (form ==
  280. POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
  281. if (len != enc_len) {
  282. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  283. return 0;
  284. }
  285. if (ctx == NULL) {
  286. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  287. if (ctx == NULL)
  288. return 0;
  289. }
  290. BN_CTX_start(ctx);
  291. x = BN_CTX_get(ctx);
  292. y = BN_CTX_get(ctx);
  293. if (y == NULL)
  294. goto err;
  295. if (!BN_bin2bn(buf + 1, field_len, x))
  296. goto err;
  297. if (BN_ucmp(x, group->field) >= 0) {
  298. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  299. goto err;
  300. }
  301. if (form == POINT_CONVERSION_COMPRESSED) {
  302. if (!EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx))
  303. goto err;
  304. } else {
  305. if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
  306. goto err;
  307. if (BN_ucmp(y, group->field) >= 0) {
  308. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  309. goto err;
  310. }
  311. if (form == POINT_CONVERSION_HYBRID) {
  312. if (y_bit != BN_is_odd(y)) {
  313. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  314. goto err;
  315. }
  316. }
  317. /*
  318. * EC_POINT_set_affine_coordinates is responsible for checking that
  319. * the point is on the curve.
  320. */
  321. if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
  322. goto err;
  323. }
  324. ret = 1;
  325. err:
  326. BN_CTX_end(ctx);
  327. BN_CTX_free(new_ctx);
  328. return ret;
  329. }