Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

1792 linhas
56 KiB

  1. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  2. * All rights reserved.
  3. *
  4. * This package is an SSL implementation written
  5. * by Eric Young (eay@cryptsoft.com).
  6. * The implementation was written so as to conform with Netscapes SSL.
  7. *
  8. * This library is free for commercial and non-commercial use as long as
  9. * the following conditions are aheared to. The following conditions
  10. * apply to all code found in this distribution, be it the RC4, RSA,
  11. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  12. * included with this distribution is covered by the same copyright terms
  13. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  14. *
  15. * Copyright remains Eric Young's, and as such any Copyright notices in
  16. * the code are not to be removed.
  17. * If this package is used in a product, Eric Young should be given attribution
  18. * as the author of the parts of the library used.
  19. * This can be in the form of a textual message at program startup or
  20. * in documentation (online or textual) provided with the package.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. * 1. Redistributions of source code must retain the copyright
  26. * notice, this list of conditions and the following disclaimer.
  27. * 2. Redistributions in binary form must reproduce the above copyright
  28. * notice, this list of conditions and the following disclaimer in the
  29. * documentation and/or other materials provided with the distribution.
  30. * 3. All advertising materials mentioning features or use of this software
  31. * must display the following acknowledgement:
  32. * "This product includes cryptographic software written by
  33. * Eric Young (eay@cryptsoft.com)"
  34. * The word 'cryptographic' can be left out if the rouines from the library
  35. * being used are not cryptographic related :-).
  36. * 4. If you include any Windows specific code (or a derivative thereof) from
  37. * the apps directory (application code) you must include an acknowledgement:
  38. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  41. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  44. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50. * SUCH DAMAGE.
  51. *
  52. * The licence and distribution terms for any publically available version or
  53. * derivative of this code cannot be changed. i.e. this code cannot simply be
  54. * copied and put under another distribution licence
  55. * [including the GNU Public Licence.]
  56. */
  57. /* ====================================================================
  58. * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  59. *
  60. * Portions of the attached software ("Contribution") are developed by
  61. * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
  62. *
  63. * The Contribution is licensed pursuant to the Eric Young open source
  64. * license provided above.
  65. *
  66. * The binary polynomial arithmetic software is originally written by
  67. * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
  68. * Laboratories. */
  69. /* Per C99, various stdint.h and inttypes.h macros (the latter used by bn.h) are
  70. * unavailable in C++ unless some macros are defined. C++11 overruled this
  71. * decision, but older Android NDKs still require it. */
  72. #if !defined(__STDC_CONSTANT_MACROS)
  73. #define __STDC_CONSTANT_MACROS
  74. #endif
  75. #if !defined(__STDC_FORMAT_MACROS)
  76. #define __STDC_FORMAT_MACROS
  77. #endif
  78. #include <assert.h>
  79. #include <errno.h>
  80. #include <limits.h>
  81. #include <stdio.h>
  82. #include <string.h>
  83. #include <utility>
  84. #include <openssl/bn.h>
  85. #include <openssl/bytestring.h>
  86. #include <openssl/crypto.h>
  87. #include <openssl/err.h>
  88. #include <openssl/mem.h>
  89. #include "../internal.h"
  90. #include "../test/file_test.h"
  91. #include "../test/test_util.h"
  92. static int HexToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
  93. BIGNUM *raw = NULL;
  94. int ret = BN_hex2bn(&raw, in);
  95. out->reset(raw);
  96. return ret;
  97. }
  98. static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *attribute) {
  99. std::string hex;
  100. if (!t->GetAttribute(&hex, attribute)) {
  101. return nullptr;
  102. }
  103. bssl::UniquePtr<BIGNUM> ret;
  104. if (HexToBIGNUM(&ret, hex.c_str()) != static_cast<int>(hex.size())) {
  105. t->PrintLine("Could not decode '%s'.", hex.c_str());
  106. return nullptr;
  107. }
  108. return ret;
  109. }
  110. static bool GetInt(FileTest *t, int *out, const char *attribute) {
  111. bssl::UniquePtr<BIGNUM> ret = GetBIGNUM(t, attribute);
  112. if (!ret) {
  113. return false;
  114. }
  115. BN_ULONG word = BN_get_word(ret.get());
  116. if (word > INT_MAX) {
  117. return false;
  118. }
  119. *out = static_cast<int>(word);
  120. return true;
  121. }
  122. static bool ExpectBIGNUMsEqual(FileTest *t, const char *operation,
  123. const BIGNUM *expected, const BIGNUM *actual) {
  124. if (BN_cmp(expected, actual) == 0) {
  125. return true;
  126. }
  127. bssl::UniquePtr<char> expected_str(BN_bn2hex(expected));
  128. bssl::UniquePtr<char> actual_str(BN_bn2hex(actual));
  129. if (!expected_str || !actual_str) {
  130. return false;
  131. }
  132. t->PrintLine("Got %s =", operation);
  133. t->PrintLine("\t%s", actual_str.get());
  134. t->PrintLine("wanted:");
  135. t->PrintLine("\t%s", expected_str.get());
  136. return false;
  137. }
  138. static bool TestSum(FileTest *t, BN_CTX *ctx) {
  139. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  140. bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
  141. bssl::UniquePtr<BIGNUM> sum = GetBIGNUM(t, "Sum");
  142. if (!a || !b || !sum) {
  143. return false;
  144. }
  145. bssl::UniquePtr<BIGNUM> ret(BN_new());
  146. if (!ret ||
  147. !BN_add(ret.get(), a.get(), b.get()) ||
  148. !ExpectBIGNUMsEqual(t, "A + B", sum.get(), ret.get()) ||
  149. !BN_sub(ret.get(), sum.get(), a.get()) ||
  150. !ExpectBIGNUMsEqual(t, "Sum - A", b.get(), ret.get()) ||
  151. !BN_sub(ret.get(), sum.get(), b.get()) ||
  152. !ExpectBIGNUMsEqual(t, "Sum - B", a.get(), ret.get())) {
  153. return false;
  154. }
  155. // Test that the functions work when |r| and |a| point to the same |BIGNUM|,
  156. // or when |r| and |b| point to the same |BIGNUM|. TODO: Test the case where
  157. // all of |r|, |a|, and |b| point to the same |BIGNUM|.
  158. if (!BN_copy(ret.get(), a.get()) ||
  159. !BN_add(ret.get(), ret.get(), b.get()) ||
  160. !ExpectBIGNUMsEqual(t, "A + B (r is a)", sum.get(), ret.get()) ||
  161. !BN_copy(ret.get(), b.get()) ||
  162. !BN_add(ret.get(), a.get(), ret.get()) ||
  163. !ExpectBIGNUMsEqual(t, "A + B (r is b)", sum.get(), ret.get()) ||
  164. !BN_copy(ret.get(), sum.get()) ||
  165. !BN_sub(ret.get(), ret.get(), a.get()) ||
  166. !ExpectBIGNUMsEqual(t, "Sum - A (r is a)", b.get(), ret.get()) ||
  167. !BN_copy(ret.get(), a.get()) ||
  168. !BN_sub(ret.get(), sum.get(), ret.get()) ||
  169. !ExpectBIGNUMsEqual(t, "Sum - A (r is b)", b.get(), ret.get()) ||
  170. !BN_copy(ret.get(), sum.get()) ||
  171. !BN_sub(ret.get(), ret.get(), b.get()) ||
  172. !ExpectBIGNUMsEqual(t, "Sum - B (r is a)", a.get(), ret.get()) ||
  173. !BN_copy(ret.get(), b.get()) ||
  174. !BN_sub(ret.get(), sum.get(), ret.get()) ||
  175. !ExpectBIGNUMsEqual(t, "Sum - B (r is b)", a.get(), ret.get())) {
  176. return false;
  177. }
  178. // Test |BN_uadd| and |BN_usub| with the prerequisites they are documented as
  179. // having. Note that these functions are frequently used when the
  180. // prerequisites don't hold. In those cases, they are supposed to work as if
  181. // the prerequisite hold, but we don't test that yet. TODO: test that.
  182. if (!BN_is_negative(a.get()) &&
  183. !BN_is_negative(b.get()) && BN_cmp(a.get(), b.get()) >= 0) {
  184. if (!BN_uadd(ret.get(), a.get(), b.get()) ||
  185. !ExpectBIGNUMsEqual(t, "A +u B", sum.get(), ret.get()) ||
  186. !BN_usub(ret.get(), sum.get(), a.get()) ||
  187. !ExpectBIGNUMsEqual(t, "Sum -u A", b.get(), ret.get()) ||
  188. !BN_usub(ret.get(), sum.get(), b.get()) ||
  189. !ExpectBIGNUMsEqual(t, "Sum -u B", a.get(), ret.get())) {
  190. return false;
  191. }
  192. // Test that the functions work when |r| and |a| point to the same |BIGNUM|,
  193. // or when |r| and |b| point to the same |BIGNUM|. TODO: Test the case where
  194. // all of |r|, |a|, and |b| point to the same |BIGNUM|.
  195. if (!BN_copy(ret.get(), a.get()) ||
  196. !BN_uadd(ret.get(), ret.get(), b.get()) ||
  197. !ExpectBIGNUMsEqual(t, "A +u B (r is a)", sum.get(), ret.get()) ||
  198. !BN_copy(ret.get(), b.get()) ||
  199. !BN_uadd(ret.get(), a.get(), ret.get()) ||
  200. !ExpectBIGNUMsEqual(t, "A +u B (r is b)", sum.get(), ret.get()) ||
  201. !BN_copy(ret.get(), sum.get()) ||
  202. !BN_usub(ret.get(), ret.get(), a.get()) ||
  203. !ExpectBIGNUMsEqual(t, "Sum -u A (r is a)", b.get(), ret.get()) ||
  204. !BN_copy(ret.get(), a.get()) ||
  205. !BN_usub(ret.get(), sum.get(), ret.get()) ||
  206. !ExpectBIGNUMsEqual(t, "Sum -u A (r is b)", b.get(), ret.get()) ||
  207. !BN_copy(ret.get(), sum.get()) ||
  208. !BN_usub(ret.get(), ret.get(), b.get()) ||
  209. !ExpectBIGNUMsEqual(t, "Sum -u B (r is a)", a.get(), ret.get()) ||
  210. !BN_copy(ret.get(), b.get()) ||
  211. !BN_usub(ret.get(), sum.get(), ret.get()) ||
  212. !ExpectBIGNUMsEqual(t, "Sum -u B (r is b)", a.get(), ret.get())) {
  213. return false;
  214. }
  215. }
  216. // Test with |BN_add_word| and |BN_sub_word| if |b| is small enough.
  217. BN_ULONG b_word = BN_get_word(b.get());
  218. if (!BN_is_negative(b.get()) && b_word != (BN_ULONG)-1) {
  219. if (!BN_copy(ret.get(), a.get()) ||
  220. !BN_add_word(ret.get(), b_word) ||
  221. !ExpectBIGNUMsEqual(t, "A + B (word)", sum.get(), ret.get()) ||
  222. !BN_copy(ret.get(), sum.get()) ||
  223. !BN_sub_word(ret.get(), b_word) ||
  224. !ExpectBIGNUMsEqual(t, "Sum - B (word)", a.get(), ret.get())) {
  225. return false;
  226. }
  227. }
  228. return true;
  229. }
  230. static bool TestLShift1(FileTest *t, BN_CTX *ctx) {
  231. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  232. bssl::UniquePtr<BIGNUM> lshift1 = GetBIGNUM(t, "LShift1");
  233. bssl::UniquePtr<BIGNUM> zero(BN_new());
  234. if (!a || !lshift1 || !zero) {
  235. return false;
  236. }
  237. BN_zero(zero.get());
  238. bssl::UniquePtr<BIGNUM> ret(BN_new()), two(BN_new()), remainder(BN_new());
  239. if (!ret || !two || !remainder ||
  240. !BN_set_word(two.get(), 2) ||
  241. !BN_add(ret.get(), a.get(), a.get()) ||
  242. !ExpectBIGNUMsEqual(t, "A + A", lshift1.get(), ret.get()) ||
  243. !BN_mul(ret.get(), a.get(), two.get(), ctx) ||
  244. !ExpectBIGNUMsEqual(t, "A * 2", lshift1.get(), ret.get()) ||
  245. !BN_div(ret.get(), remainder.get(), lshift1.get(), two.get(), ctx) ||
  246. !ExpectBIGNUMsEqual(t, "LShift1 / 2", a.get(), ret.get()) ||
  247. !ExpectBIGNUMsEqual(t, "LShift1 % 2", zero.get(), remainder.get()) ||
  248. !BN_lshift1(ret.get(), a.get()) ||
  249. !ExpectBIGNUMsEqual(t, "A << 1", lshift1.get(), ret.get()) ||
  250. !BN_rshift1(ret.get(), lshift1.get()) ||
  251. !ExpectBIGNUMsEqual(t, "LShift >> 1", a.get(), ret.get()) ||
  252. !BN_rshift1(ret.get(), lshift1.get()) ||
  253. !ExpectBIGNUMsEqual(t, "LShift >> 1", a.get(), ret.get())) {
  254. return false;
  255. }
  256. // Set the LSB to 1 and test rshift1 again.
  257. if (!BN_set_bit(lshift1.get(), 0) ||
  258. !BN_div(ret.get(), nullptr /* rem */, lshift1.get(), two.get(), ctx) ||
  259. !ExpectBIGNUMsEqual(t, "(LShift1 | 1) / 2", a.get(), ret.get()) ||
  260. !BN_rshift1(ret.get(), lshift1.get()) ||
  261. !ExpectBIGNUMsEqual(t, "(LShift | 1) >> 1", a.get(), ret.get())) {
  262. return false;
  263. }
  264. return true;
  265. }
  266. static bool TestLShift(FileTest *t, BN_CTX *ctx) {
  267. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  268. bssl::UniquePtr<BIGNUM> lshift = GetBIGNUM(t, "LShift");
  269. int n = 0;
  270. if (!a || !lshift || !GetInt(t, &n, "N")) {
  271. return false;
  272. }
  273. bssl::UniquePtr<BIGNUM> ret(BN_new());
  274. if (!ret ||
  275. !BN_lshift(ret.get(), a.get(), n) ||
  276. !ExpectBIGNUMsEqual(t, "A << N", lshift.get(), ret.get()) ||
  277. !BN_rshift(ret.get(), lshift.get(), n) ||
  278. !ExpectBIGNUMsEqual(t, "A >> N", a.get(), ret.get())) {
  279. return false;
  280. }
  281. return true;
  282. }
  283. static bool TestRShift(FileTest *t, BN_CTX *ctx) {
  284. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  285. bssl::UniquePtr<BIGNUM> rshift = GetBIGNUM(t, "RShift");
  286. int n = 0;
  287. if (!a || !rshift || !GetInt(t, &n, "N")) {
  288. return false;
  289. }
  290. bssl::UniquePtr<BIGNUM> ret(BN_new());
  291. if (!ret ||
  292. !BN_rshift(ret.get(), a.get(), n) ||
  293. !ExpectBIGNUMsEqual(t, "A >> N", rshift.get(), ret.get())) {
  294. return false;
  295. }
  296. return true;
  297. }
  298. static bool TestSquare(FileTest *t, BN_CTX *ctx) {
  299. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  300. bssl::UniquePtr<BIGNUM> square = GetBIGNUM(t, "Square");
  301. bssl::UniquePtr<BIGNUM> zero(BN_new());
  302. if (!a || !square || !zero) {
  303. return false;
  304. }
  305. BN_zero(zero.get());
  306. bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
  307. if (!ret || !remainder ||
  308. !BN_sqr(ret.get(), a.get(), ctx) ||
  309. !ExpectBIGNUMsEqual(t, "A^2", square.get(), ret.get()) ||
  310. !BN_mul(ret.get(), a.get(), a.get(), ctx) ||
  311. !ExpectBIGNUMsEqual(t, "A * A", square.get(), ret.get()) ||
  312. !BN_div(ret.get(), remainder.get(), square.get(), a.get(), ctx) ||
  313. !ExpectBIGNUMsEqual(t, "Square / A", a.get(), ret.get()) ||
  314. !ExpectBIGNUMsEqual(t, "Square % A", zero.get(), remainder.get())) {
  315. return false;
  316. }
  317. BN_set_negative(a.get(), 0);
  318. if (!BN_sqrt(ret.get(), square.get(), ctx) ||
  319. !ExpectBIGNUMsEqual(t, "sqrt(Square)", a.get(), ret.get())) {
  320. return false;
  321. }
  322. // BN_sqrt should fail on non-squares and negative numbers.
  323. if (!BN_is_zero(square.get())) {
  324. bssl::UniquePtr<BIGNUM> tmp(BN_new());
  325. if (!tmp || !BN_copy(tmp.get(), square.get())) {
  326. return false;
  327. }
  328. BN_set_negative(tmp.get(), 1);
  329. if (BN_sqrt(ret.get(), tmp.get(), ctx)) {
  330. t->PrintLine("BN_sqrt succeeded on a negative number");
  331. return false;
  332. }
  333. ERR_clear_error();
  334. BN_set_negative(tmp.get(), 0);
  335. if (!BN_add(tmp.get(), tmp.get(), BN_value_one())) {
  336. return false;
  337. }
  338. if (BN_sqrt(ret.get(), tmp.get(), ctx)) {
  339. t->PrintLine("BN_sqrt succeeded on a non-square");
  340. return false;
  341. }
  342. ERR_clear_error();
  343. }
  344. return true;
  345. }
  346. static bool TestProduct(FileTest *t, BN_CTX *ctx) {
  347. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  348. bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
  349. bssl::UniquePtr<BIGNUM> product = GetBIGNUM(t, "Product");
  350. bssl::UniquePtr<BIGNUM> zero(BN_new());
  351. if (!a || !b || !product || !zero) {
  352. return false;
  353. }
  354. BN_zero(zero.get());
  355. bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
  356. if (!ret || !remainder ||
  357. !BN_mul(ret.get(), a.get(), b.get(), ctx) ||
  358. !ExpectBIGNUMsEqual(t, "A * B", product.get(), ret.get()) ||
  359. !BN_div(ret.get(), remainder.get(), product.get(), a.get(), ctx) ||
  360. !ExpectBIGNUMsEqual(t, "Product / A", b.get(), ret.get()) ||
  361. !ExpectBIGNUMsEqual(t, "Product % A", zero.get(), remainder.get()) ||
  362. !BN_div(ret.get(), remainder.get(), product.get(), b.get(), ctx) ||
  363. !ExpectBIGNUMsEqual(t, "Product / B", a.get(), ret.get()) ||
  364. !ExpectBIGNUMsEqual(t, "Product % B", zero.get(), remainder.get())) {
  365. return false;
  366. }
  367. return true;
  368. }
  369. static bool TestQuotient(FileTest *t, BN_CTX *ctx) {
  370. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  371. bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
  372. bssl::UniquePtr<BIGNUM> quotient = GetBIGNUM(t, "Quotient");
  373. bssl::UniquePtr<BIGNUM> remainder = GetBIGNUM(t, "Remainder");
  374. if (!a || !b || !quotient || !remainder) {
  375. return false;
  376. }
  377. bssl::UniquePtr<BIGNUM> ret(BN_new()), ret2(BN_new());
  378. if (!ret || !ret2 ||
  379. !BN_div(ret.get(), ret2.get(), a.get(), b.get(), ctx) ||
  380. !ExpectBIGNUMsEqual(t, "A / B", quotient.get(), ret.get()) ||
  381. !ExpectBIGNUMsEqual(t, "A % B", remainder.get(), ret2.get()) ||
  382. !BN_mul(ret.get(), quotient.get(), b.get(), ctx) ||
  383. !BN_add(ret.get(), ret.get(), remainder.get()) ||
  384. !ExpectBIGNUMsEqual(t, "Quotient * B + Remainder", a.get(), ret.get())) {
  385. return false;
  386. }
  387. // Test with |BN_mod_word| and |BN_div_word| if the divisor is small enough.
  388. BN_ULONG b_word = BN_get_word(b.get());
  389. if (!BN_is_negative(b.get()) && b_word != (BN_ULONG)-1) {
  390. BN_ULONG remainder_word = BN_get_word(remainder.get());
  391. assert(remainder_word != (BN_ULONG)-1);
  392. if (!BN_copy(ret.get(), a.get())) {
  393. return false;
  394. }
  395. BN_ULONG ret_word = BN_div_word(ret.get(), b_word);
  396. if (ret_word != remainder_word) {
  397. t->PrintLine("Got A %% B (word) = " BN_HEX_FMT1 ", wanted " BN_HEX_FMT1
  398. "\n",
  399. ret_word, remainder_word);
  400. return false;
  401. }
  402. if (!ExpectBIGNUMsEqual(t, "A / B (word)", quotient.get(), ret.get())) {
  403. return false;
  404. }
  405. ret_word = BN_mod_word(a.get(), b_word);
  406. if (ret_word != remainder_word) {
  407. t->PrintLine("Got A %% B (word) = " BN_HEX_FMT1 ", wanted " BN_HEX_FMT1
  408. "\n",
  409. ret_word, remainder_word);
  410. return false;
  411. }
  412. }
  413. // Test BN_nnmod.
  414. if (!BN_is_negative(b.get())) {
  415. bssl::UniquePtr<BIGNUM> nnmod(BN_new());
  416. if (!nnmod ||
  417. !BN_copy(nnmod.get(), remainder.get()) ||
  418. (BN_is_negative(nnmod.get()) &&
  419. !BN_add(nnmod.get(), nnmod.get(), b.get())) ||
  420. !BN_nnmod(ret.get(), a.get(), b.get(), ctx) ||
  421. !ExpectBIGNUMsEqual(t, "A % B (non-negative)", nnmod.get(),
  422. ret.get())) {
  423. return false;
  424. }
  425. }
  426. return true;
  427. }
  428. static bool TestModMul(FileTest *t, BN_CTX *ctx) {
  429. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  430. bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
  431. bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
  432. bssl::UniquePtr<BIGNUM> mod_mul = GetBIGNUM(t, "ModMul");
  433. if (!a || !b || !m || !mod_mul) {
  434. return false;
  435. }
  436. bssl::UniquePtr<BIGNUM> ret(BN_new());
  437. if (!ret ||
  438. !BN_mod_mul(ret.get(), a.get(), b.get(), m.get(), ctx) ||
  439. !ExpectBIGNUMsEqual(t, "A * B (mod M)", mod_mul.get(), ret.get())) {
  440. return false;
  441. }
  442. if (BN_is_odd(m.get())) {
  443. // Reduce |a| and |b| and test the Montgomery version.
  444. bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
  445. bssl::UniquePtr<BIGNUM> a_tmp(BN_new()), b_tmp(BN_new());
  446. if (!mont || !a_tmp || !b_tmp ||
  447. !BN_MONT_CTX_set(mont.get(), m.get(), ctx) ||
  448. !BN_nnmod(a_tmp.get(), a.get(), m.get(), ctx) ||
  449. !BN_nnmod(b_tmp.get(), b.get(), m.get(), ctx) ||
  450. !BN_to_montgomery(a_tmp.get(), a_tmp.get(), mont.get(), ctx) ||
  451. !BN_to_montgomery(b_tmp.get(), b_tmp.get(), mont.get(), ctx) ||
  452. !BN_mod_mul_montgomery(ret.get(), a_tmp.get(), b_tmp.get(), mont.get(),
  453. ctx) ||
  454. !BN_from_montgomery(ret.get(), ret.get(), mont.get(), ctx) ||
  455. !ExpectBIGNUMsEqual(t, "A * B (mod M) (Montgomery)",
  456. mod_mul.get(), ret.get())) {
  457. return false;
  458. }
  459. }
  460. return true;
  461. }
  462. static bool TestModSquare(FileTest *t, BN_CTX *ctx) {
  463. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  464. bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
  465. bssl::UniquePtr<BIGNUM> mod_square = GetBIGNUM(t, "ModSquare");
  466. if (!a || !m || !mod_square) {
  467. return false;
  468. }
  469. bssl::UniquePtr<BIGNUM> a_copy(BN_new());
  470. bssl::UniquePtr<BIGNUM> ret(BN_new());
  471. if (!ret || !a_copy ||
  472. !BN_mod_mul(ret.get(), a.get(), a.get(), m.get(), ctx) ||
  473. !ExpectBIGNUMsEqual(t, "A * A (mod M)", mod_square.get(), ret.get()) ||
  474. // Repeat the operation with |a_copy|.
  475. !BN_copy(a_copy.get(), a.get()) ||
  476. !BN_mod_mul(ret.get(), a.get(), a_copy.get(), m.get(), ctx) ||
  477. !ExpectBIGNUMsEqual(t, "A * A_copy (mod M)", mod_square.get(),
  478. ret.get())) {
  479. return false;
  480. }
  481. if (BN_is_odd(m.get())) {
  482. // Reduce |a| and test the Montgomery version.
  483. bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
  484. bssl::UniquePtr<BIGNUM> a_tmp(BN_new());
  485. if (!mont || !a_tmp ||
  486. !BN_MONT_CTX_set(mont.get(), m.get(), ctx) ||
  487. !BN_nnmod(a_tmp.get(), a.get(), m.get(), ctx) ||
  488. !BN_to_montgomery(a_tmp.get(), a_tmp.get(), mont.get(), ctx) ||
  489. !BN_mod_mul_montgomery(ret.get(), a_tmp.get(), a_tmp.get(), mont.get(),
  490. ctx) ||
  491. !BN_from_montgomery(ret.get(), ret.get(), mont.get(), ctx) ||
  492. !ExpectBIGNUMsEqual(t, "A * A (mod M) (Montgomery)",
  493. mod_square.get(), ret.get()) ||
  494. // Repeat the operation with |a_copy|.
  495. !BN_copy(a_copy.get(), a_tmp.get()) ||
  496. !BN_mod_mul_montgomery(ret.get(), a_tmp.get(), a_copy.get(), mont.get(),
  497. ctx) ||
  498. !BN_from_montgomery(ret.get(), ret.get(), mont.get(), ctx) ||
  499. !ExpectBIGNUMsEqual(t, "A * A_copy (mod M) (Montgomery)",
  500. mod_square.get(), ret.get())) {
  501. return false;
  502. }
  503. }
  504. return true;
  505. }
  506. static bool TestModExp(FileTest *t, BN_CTX *ctx) {
  507. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  508. bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
  509. bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
  510. bssl::UniquePtr<BIGNUM> mod_exp = GetBIGNUM(t, "ModExp");
  511. if (!a || !e || !m || !mod_exp) {
  512. return false;
  513. }
  514. bssl::UniquePtr<BIGNUM> ret(BN_new());
  515. if (!ret ||
  516. !BN_mod_exp(ret.get(), a.get(), e.get(), m.get(), ctx) ||
  517. !ExpectBIGNUMsEqual(t, "A ^ E (mod M)", mod_exp.get(), ret.get())) {
  518. return false;
  519. }
  520. if (BN_is_odd(m.get())) {
  521. if (!BN_mod_exp_mont(ret.get(), a.get(), e.get(), m.get(), ctx, NULL) ||
  522. !ExpectBIGNUMsEqual(t, "A ^ E (mod M) (Montgomery)", mod_exp.get(),
  523. ret.get()) ||
  524. !BN_mod_exp_mont_consttime(ret.get(), a.get(), e.get(), m.get(), ctx,
  525. NULL) ||
  526. !ExpectBIGNUMsEqual(t, "A ^ E (mod M) (constant-time)", mod_exp.get(),
  527. ret.get())) {
  528. return false;
  529. }
  530. }
  531. return true;
  532. }
  533. static bool TestExp(FileTest *t, BN_CTX *ctx) {
  534. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  535. bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
  536. bssl::UniquePtr<BIGNUM> exp = GetBIGNUM(t, "Exp");
  537. if (!a || !e || !exp) {
  538. return false;
  539. }
  540. bssl::UniquePtr<BIGNUM> ret(BN_new());
  541. if (!ret ||
  542. !BN_exp(ret.get(), a.get(), e.get(), ctx) ||
  543. !ExpectBIGNUMsEqual(t, "A ^ E", exp.get(), ret.get())) {
  544. return false;
  545. }
  546. return true;
  547. }
  548. static bool TestModSqrt(FileTest *t, BN_CTX *ctx) {
  549. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  550. bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
  551. bssl::UniquePtr<BIGNUM> mod_sqrt = GetBIGNUM(t, "ModSqrt");
  552. bssl::UniquePtr<BIGNUM> mod_sqrt2(BN_new());
  553. if (!a || !p || !mod_sqrt || !mod_sqrt2 ||
  554. // There are two possible answers.
  555. !BN_sub(mod_sqrt2.get(), p.get(), mod_sqrt.get())) {
  556. return false;
  557. }
  558. // -0 is 0, not P.
  559. if (BN_is_zero(mod_sqrt.get())) {
  560. BN_zero(mod_sqrt2.get());
  561. }
  562. bssl::UniquePtr<BIGNUM> ret(BN_new());
  563. if (!ret ||
  564. !BN_mod_sqrt(ret.get(), a.get(), p.get(), ctx)) {
  565. return false;
  566. }
  567. if (BN_cmp(ret.get(), mod_sqrt2.get()) != 0 &&
  568. !ExpectBIGNUMsEqual(t, "sqrt(A) (mod P)", mod_sqrt.get(), ret.get())) {
  569. return false;
  570. }
  571. return true;
  572. }
  573. static bool TestNotModSquare(FileTest *t, BN_CTX *ctx) {
  574. bssl::UniquePtr<BIGNUM> not_mod_square = GetBIGNUM(t, "NotModSquare");
  575. bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
  576. bssl::UniquePtr<BIGNUM> ret(BN_new());
  577. if (!not_mod_square || !p || !ret) {
  578. return false;
  579. }
  580. if (BN_mod_sqrt(ret.get(), not_mod_square.get(), p.get(), ctx)) {
  581. t->PrintLine("BN_mod_sqrt unexpectedly succeeded.");
  582. return false;
  583. }
  584. uint32_t err = ERR_peek_error();
  585. if (ERR_GET_LIB(err) == ERR_LIB_BN &&
  586. ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
  587. ERR_clear_error();
  588. return true;
  589. }
  590. return false;
  591. }
  592. static bool TestModInv(FileTest *t, BN_CTX *ctx) {
  593. bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
  594. bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
  595. bssl::UniquePtr<BIGNUM> mod_inv = GetBIGNUM(t, "ModInv");
  596. if (!a || !m || !mod_inv) {
  597. return false;
  598. }
  599. bssl::UniquePtr<BIGNUM> ret(BN_new());
  600. if (!ret ||
  601. !BN_mod_inverse(ret.get(), a.get(), m.get(), ctx) ||
  602. !ExpectBIGNUMsEqual(t, "inv(A) (mod M)", mod_inv.get(), ret.get())) {
  603. return false;
  604. }
  605. return true;
  606. }
  607. struct Test {
  608. const char *name;
  609. bool (*func)(FileTest *t, BN_CTX *ctx);
  610. };
  611. static const Test kTests[] = {
  612. {"Sum", TestSum},
  613. {"LShift1", TestLShift1},
  614. {"LShift", TestLShift},
  615. {"RShift", TestRShift},
  616. {"Square", TestSquare},
  617. {"Product", TestProduct},
  618. {"Quotient", TestQuotient},
  619. {"ModMul", TestModMul},
  620. {"ModSquare", TestModSquare},
  621. {"ModExp", TestModExp},
  622. {"Exp", TestExp},
  623. {"ModSqrt", TestModSqrt},
  624. {"NotModSquare", TestNotModSquare},
  625. {"ModInv", TestModInv},
  626. };
  627. static bool RunTest(FileTest *t, void *arg) {
  628. BN_CTX *ctx = reinterpret_cast<BN_CTX *>(arg);
  629. for (const Test &test : kTests) {
  630. if (t->GetType() != test.name) {
  631. continue;
  632. }
  633. return test.func(t, ctx);
  634. }
  635. t->PrintLine("Unknown test type: %s", t->GetType().c_str());
  636. return false;
  637. }
  638. static bool TestBN2BinPadded(BN_CTX *ctx) {
  639. uint8_t zeros[256], out[256], reference[128];
  640. OPENSSL_memset(zeros, 0, sizeof(zeros));
  641. // Test edge case at 0.
  642. bssl::UniquePtr<BIGNUM> n(BN_new());
  643. if (!n || !BN_bn2bin_padded(NULL, 0, n.get())) {
  644. fprintf(stderr,
  645. "BN_bn2bin_padded failed to encode 0 in an empty buffer.\n");
  646. return false;
  647. }
  648. OPENSSL_memset(out, -1, sizeof(out));
  649. if (!BN_bn2bin_padded(out, sizeof(out), n.get())) {
  650. fprintf(stderr,
  651. "BN_bn2bin_padded failed to encode 0 in a non-empty buffer.\n");
  652. return false;
  653. }
  654. if (OPENSSL_memcmp(zeros, out, sizeof(out))) {
  655. fprintf(stderr, "BN_bn2bin_padded did not zero buffer.\n");
  656. return false;
  657. }
  658. // Test a random numbers at various byte lengths.
  659. for (size_t bytes = 128 - 7; bytes <= 128; bytes++) {
  660. if (!BN_rand(n.get(), bytes * 8, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
  661. ERR_print_errors_fp(stderr);
  662. return false;
  663. }
  664. if (BN_num_bytes(n.get()) != bytes ||
  665. BN_bn2bin(n.get(), reference) != bytes) {
  666. fprintf(stderr, "Bad result from BN_rand; bytes.\n");
  667. return false;
  668. }
  669. // Empty buffer should fail.
  670. if (BN_bn2bin_padded(NULL, 0, n.get())) {
  671. fprintf(stderr,
  672. "BN_bn2bin_padded incorrectly succeeded on empty buffer.\n");
  673. return false;
  674. }
  675. // One byte short should fail.
  676. if (BN_bn2bin_padded(out, bytes - 1, n.get())) {
  677. fprintf(stderr, "BN_bn2bin_padded incorrectly succeeded on short.\n");
  678. return false;
  679. }
  680. // Exactly right size should encode.
  681. if (!BN_bn2bin_padded(out, bytes, n.get()) ||
  682. OPENSSL_memcmp(out, reference, bytes) != 0) {
  683. fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
  684. return false;
  685. }
  686. // Pad up one byte extra.
  687. if (!BN_bn2bin_padded(out, bytes + 1, n.get()) ||
  688. OPENSSL_memcmp(out + 1, reference, bytes) ||
  689. OPENSSL_memcmp(out, zeros, 1)) {
  690. fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
  691. return false;
  692. }
  693. // Pad up to 256.
  694. if (!BN_bn2bin_padded(out, sizeof(out), n.get()) ||
  695. OPENSSL_memcmp(out + sizeof(out) - bytes, reference, bytes) ||
  696. OPENSSL_memcmp(out, zeros, sizeof(out) - bytes)) {
  697. fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
  698. return false;
  699. }
  700. }
  701. return true;
  702. }
  703. static bool TestLittleEndian() {
  704. bssl::UniquePtr<BIGNUM> x(BN_new());
  705. bssl::UniquePtr<BIGNUM> y(BN_new());
  706. if (!x || !y) {
  707. fprintf(stderr, "BN_new failed to malloc.\n");
  708. return false;
  709. }
  710. // Test edge case at 0. Fill |out| with garbage to ensure |BN_bn2le_padded|
  711. // wrote the result.
  712. uint8_t out[256], zeros[256];
  713. OPENSSL_memset(out, -1, sizeof(out));
  714. OPENSSL_memset(zeros, 0, sizeof(zeros));
  715. if (!BN_bn2le_padded(out, sizeof(out), x.get()) ||
  716. OPENSSL_memcmp(zeros, out, sizeof(out))) {
  717. fprintf(stderr, "BN_bn2le_padded failed to encode 0.\n");
  718. return false;
  719. }
  720. if (!BN_le2bn(out, sizeof(out), y.get()) ||
  721. BN_cmp(x.get(), y.get()) != 0) {
  722. fprintf(stderr, "BN_le2bn failed to decode 0 correctly.\n");
  723. return false;
  724. }
  725. // Test random numbers at various byte lengths.
  726. for (size_t bytes = 128 - 7; bytes <= 128; bytes++) {
  727. if (!BN_rand(x.get(), bytes * 8, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
  728. ERR_print_errors_fp(stderr);
  729. return false;
  730. }
  731. // Fill |out| with garbage to ensure |BN_bn2le_padded| wrote the result.
  732. OPENSSL_memset(out, -1, sizeof(out));
  733. if (!BN_bn2le_padded(out, sizeof(out), x.get())) {
  734. fprintf(stderr, "BN_bn2le_padded failed to encode random value.\n");
  735. return false;
  736. }
  737. // Compute the expected value by reversing the big-endian output.
  738. uint8_t expected[sizeof(out)];
  739. if (!BN_bn2bin_padded(expected, sizeof(expected), x.get())) {
  740. return false;
  741. }
  742. for (size_t i = 0; i < sizeof(expected) / 2; i++) {
  743. uint8_t tmp = expected[i];
  744. expected[i] = expected[sizeof(expected) - 1 - i];
  745. expected[sizeof(expected) - 1 - i] = tmp;
  746. }
  747. if (OPENSSL_memcmp(expected, out, sizeof(out))) {
  748. fprintf(stderr, "BN_bn2le_padded failed to encode value correctly.\n");
  749. hexdump(stderr, "Expected: ", expected, sizeof(expected));
  750. hexdump(stderr, "Got: ", out, sizeof(out));
  751. return false;
  752. }
  753. // Make sure the decoding produces the same BIGNUM.
  754. if (!BN_le2bn(out, bytes, y.get()) ||
  755. BN_cmp(x.get(), y.get()) != 0) {
  756. bssl::UniquePtr<char> x_hex(BN_bn2hex(x.get())),
  757. y_hex(BN_bn2hex(y.get()));
  758. if (!x_hex || !y_hex) {
  759. return false;
  760. }
  761. fprintf(stderr, "BN_le2bn failed to decode value correctly.\n");
  762. fprintf(stderr, "Expected: %s\n", x_hex.get());
  763. hexdump(stderr, "Encoding: ", out, bytes);
  764. fprintf(stderr, "Got: %s\n", y_hex.get());
  765. return false;
  766. }
  767. }
  768. return true;
  769. }
  770. static int DecimalToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
  771. BIGNUM *raw = NULL;
  772. int ret = BN_dec2bn(&raw, in);
  773. out->reset(raw);
  774. return ret;
  775. }
  776. static bool TestDec2BN(BN_CTX *ctx) {
  777. bssl::UniquePtr<BIGNUM> bn;
  778. int ret = DecimalToBIGNUM(&bn, "0");
  779. if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
  780. fprintf(stderr, "BN_dec2bn gave a bad result.\n");
  781. return false;
  782. }
  783. ret = DecimalToBIGNUM(&bn, "256");
  784. if (ret != 3 || !BN_is_word(bn.get(), 256) || BN_is_negative(bn.get())) {
  785. fprintf(stderr, "BN_dec2bn gave a bad result.\n");
  786. return false;
  787. }
  788. ret = DecimalToBIGNUM(&bn, "-42");
  789. if (ret != 3 || !BN_abs_is_word(bn.get(), 42) || !BN_is_negative(bn.get())) {
  790. fprintf(stderr, "BN_dec2bn gave a bad result.\n");
  791. return false;
  792. }
  793. ret = DecimalToBIGNUM(&bn, "-0");
  794. if (ret != 2 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
  795. fprintf(stderr, "BN_dec2bn gave a bad result.\n");
  796. return false;
  797. }
  798. ret = DecimalToBIGNUM(&bn, "42trailing garbage is ignored");
  799. if (ret != 2 || !BN_abs_is_word(bn.get(), 42) || BN_is_negative(bn.get())) {
  800. fprintf(stderr, "BN_dec2bn gave a bad result.\n");
  801. return false;
  802. }
  803. return true;
  804. }
  805. static bool TestHex2BN(BN_CTX *ctx) {
  806. bssl::UniquePtr<BIGNUM> bn;
  807. int ret = HexToBIGNUM(&bn, "0");
  808. if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
  809. fprintf(stderr, "BN_hex2bn gave a bad result.\n");
  810. return false;
  811. }
  812. ret = HexToBIGNUM(&bn, "256");
  813. if (ret != 3 || !BN_is_word(bn.get(), 0x256) || BN_is_negative(bn.get())) {
  814. fprintf(stderr, "BN_hex2bn gave a bad result.\n");
  815. return false;
  816. }
  817. ret = HexToBIGNUM(&bn, "-42");
  818. if (ret != 3 || !BN_abs_is_word(bn.get(), 0x42) || !BN_is_negative(bn.get())) {
  819. fprintf(stderr, "BN_hex2bn gave a bad result.\n");
  820. return false;
  821. }
  822. ret = HexToBIGNUM(&bn, "-0");
  823. if (ret != 2 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
  824. fprintf(stderr, "BN_hex2bn gave a bad result.\n");
  825. return false;
  826. }
  827. ret = HexToBIGNUM(&bn, "abctrailing garbage is ignored");
  828. if (ret != 3 || !BN_is_word(bn.get(), 0xabc) || BN_is_negative(bn.get())) {
  829. fprintf(stderr, "BN_hex2bn gave a bad result.\n");
  830. return false;
  831. }
  832. return true;
  833. }
  834. static bssl::UniquePtr<BIGNUM> ASCIIToBIGNUM(const char *in) {
  835. BIGNUM *raw = NULL;
  836. if (!BN_asc2bn(&raw, in)) {
  837. return nullptr;
  838. }
  839. return bssl::UniquePtr<BIGNUM>(raw);
  840. }
  841. static bool TestASC2BN(BN_CTX *ctx) {
  842. bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM("0");
  843. if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
  844. fprintf(stderr, "BN_asc2bn gave a bad result.\n");
  845. return false;
  846. }
  847. bn = ASCIIToBIGNUM("256");
  848. if (!bn || !BN_is_word(bn.get(), 256) || BN_is_negative(bn.get())) {
  849. fprintf(stderr, "BN_asc2bn gave a bad result.\n");
  850. return false;
  851. }
  852. bn = ASCIIToBIGNUM("-42");
  853. if (!bn || !BN_abs_is_word(bn.get(), 42) || !BN_is_negative(bn.get())) {
  854. fprintf(stderr, "BN_asc2bn gave a bad result.\n");
  855. return false;
  856. }
  857. bn = ASCIIToBIGNUM("0x1234");
  858. if (!bn || !BN_is_word(bn.get(), 0x1234) || BN_is_negative(bn.get())) {
  859. fprintf(stderr, "BN_asc2bn gave a bad result.\n");
  860. return false;
  861. }
  862. bn = ASCIIToBIGNUM("0X1234");
  863. if (!bn || !BN_is_word(bn.get(), 0x1234) || BN_is_negative(bn.get())) {
  864. fprintf(stderr, "BN_asc2bn gave a bad result.\n");
  865. return false;
  866. }
  867. bn = ASCIIToBIGNUM("-0xabcd");
  868. if (!bn || !BN_abs_is_word(bn.get(), 0xabcd) || !BN_is_negative(bn.get())) {
  869. fprintf(stderr, "BN_asc2bn gave a bad result.\n");
  870. return false;
  871. }
  872. bn = ASCIIToBIGNUM("-0");
  873. if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
  874. fprintf(stderr, "BN_asc2bn gave a bad result.\n");
  875. return false;
  876. }
  877. bn = ASCIIToBIGNUM("123trailing garbage is ignored");
  878. if (!bn || !BN_is_word(bn.get(), 123) || BN_is_negative(bn.get())) {
  879. fprintf(stderr, "BN_asc2bn gave a bad result.\n");
  880. return false;
  881. }
  882. return true;
  883. }
  884. struct MPITest {
  885. const char *base10;
  886. const char *mpi;
  887. size_t mpi_len;
  888. };
  889. static const MPITest kMPITests[] = {
  890. { "0", "\x00\x00\x00\x00", 4 },
  891. { "1", "\x00\x00\x00\x01\x01", 5 },
  892. { "-1", "\x00\x00\x00\x01\x81", 5 },
  893. { "128", "\x00\x00\x00\x02\x00\x80", 6 },
  894. { "256", "\x00\x00\x00\x02\x01\x00", 6 },
  895. { "-256", "\x00\x00\x00\x02\x81\x00", 6 },
  896. };
  897. static bool TestMPI() {
  898. uint8_t scratch[8];
  899. for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMPITests); i++) {
  900. const MPITest &test = kMPITests[i];
  901. bssl::UniquePtr<BIGNUM> bn(ASCIIToBIGNUM(test.base10));
  902. if (!bn) {
  903. return false;
  904. }
  905. const size_t mpi_len = BN_bn2mpi(bn.get(), NULL);
  906. if (mpi_len > sizeof(scratch)) {
  907. fprintf(stderr, "MPI test #%u: MPI size is too large to test.\n",
  908. (unsigned)i);
  909. return false;
  910. }
  911. const size_t mpi_len2 = BN_bn2mpi(bn.get(), scratch);
  912. if (mpi_len != mpi_len2) {
  913. fprintf(stderr, "MPI test #%u: length changes.\n", (unsigned)i);
  914. return false;
  915. }
  916. if (mpi_len != test.mpi_len ||
  917. OPENSSL_memcmp(test.mpi, scratch, mpi_len) != 0) {
  918. fprintf(stderr, "MPI test #%u failed:\n", (unsigned)i);
  919. hexdump(stderr, "Expected: ", test.mpi, test.mpi_len);
  920. hexdump(stderr, "Got: ", scratch, mpi_len);
  921. return false;
  922. }
  923. bssl::UniquePtr<BIGNUM> bn2(BN_mpi2bn(scratch, mpi_len, NULL));
  924. if (bn2.get() == nullptr) {
  925. fprintf(stderr, "MPI test #%u: failed to parse\n", (unsigned)i);
  926. return false;
  927. }
  928. if (BN_cmp(bn.get(), bn2.get()) != 0) {
  929. fprintf(stderr, "MPI test #%u: wrong result\n", (unsigned)i);
  930. return false;
  931. }
  932. }
  933. return true;
  934. }
  935. static bool TestRand() {
  936. bssl::UniquePtr<BIGNUM> bn(BN_new());
  937. if (!bn) {
  938. return false;
  939. }
  940. // Test BN_rand accounts for degenerate cases with |top| and |bottom|
  941. // parameters.
  942. if (!BN_rand(bn.get(), 0, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY) ||
  943. !BN_is_zero(bn.get())) {
  944. fprintf(stderr, "BN_rand gave a bad result.\n");
  945. return false;
  946. }
  947. if (!BN_rand(bn.get(), 0, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD) ||
  948. !BN_is_zero(bn.get())) {
  949. fprintf(stderr, "BN_rand gave a bad result.\n");
  950. return false;
  951. }
  952. if (!BN_rand(bn.get(), 1, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY) ||
  953. !BN_is_word(bn.get(), 1)) {
  954. fprintf(stderr, "BN_rand gave a bad result.\n");
  955. return false;
  956. }
  957. if (!BN_rand(bn.get(), 1, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY) ||
  958. !BN_is_word(bn.get(), 1)) {
  959. fprintf(stderr, "BN_rand gave a bad result.\n");
  960. return false;
  961. }
  962. if (!BN_rand(bn.get(), 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ODD) ||
  963. !BN_is_word(bn.get(), 1)) {
  964. fprintf(stderr, "BN_rand gave a bad result.\n");
  965. return false;
  966. }
  967. if (!BN_rand(bn.get(), 2, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY) ||
  968. !BN_is_word(bn.get(), 3)) {
  969. fprintf(stderr, "BN_rand gave a bad result.\n");
  970. return false;
  971. }
  972. return true;
  973. }
  974. struct ASN1Test {
  975. const char *value_ascii;
  976. const char *der;
  977. size_t der_len;
  978. };
  979. static const ASN1Test kASN1Tests[] = {
  980. {"0", "\x02\x01\x00", 3},
  981. {"1", "\x02\x01\x01", 3},
  982. {"127", "\x02\x01\x7f", 3},
  983. {"128", "\x02\x02\x00\x80", 4},
  984. {"0xdeadbeef", "\x02\x05\x00\xde\xad\xbe\xef", 7},
  985. {"0x0102030405060708",
  986. "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
  987. {"0xffffffffffffffff",
  988. "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
  989. };
  990. struct ASN1InvalidTest {
  991. const char *der;
  992. size_t der_len;
  993. };
  994. static const ASN1InvalidTest kASN1InvalidTests[] = {
  995. // Bad tag.
  996. {"\x03\x01\x00", 3},
  997. // Empty contents.
  998. {"\x02\x00", 2},
  999. };
  1000. // kASN1BuggyTests contains incorrect encodings and the corresponding, expected
  1001. // results of |BN_parse_asn1_unsigned_buggy| given that input.
  1002. static const ASN1Test kASN1BuggyTests[] = {
  1003. // Negative numbers.
  1004. {"128", "\x02\x01\x80", 3},
  1005. {"255", "\x02\x01\xff", 3},
  1006. // Unnecessary leading zeros.
  1007. {"1", "\x02\x02\x00\x01", 4},
  1008. };
  1009. static bool TestASN1() {
  1010. for (const ASN1Test &test : kASN1Tests) {
  1011. bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM(test.value_ascii);
  1012. if (!bn) {
  1013. return false;
  1014. }
  1015. // Test that the input is correctly parsed.
  1016. bssl::UniquePtr<BIGNUM> bn2(BN_new());
  1017. if (!bn2) {
  1018. return false;
  1019. }
  1020. CBS cbs;
  1021. CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
  1022. if (!BN_parse_asn1_unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
  1023. fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
  1024. return false;
  1025. }
  1026. if (BN_cmp(bn.get(), bn2.get()) != 0) {
  1027. fprintf(stderr, "Bad parse.\n");
  1028. return false;
  1029. }
  1030. // Test the value serializes correctly.
  1031. bssl::ScopedCBB cbb;
  1032. uint8_t *der;
  1033. size_t der_len;
  1034. if (!CBB_init(cbb.get(), 0) ||
  1035. !BN_marshal_asn1(cbb.get(), bn.get()) ||
  1036. !CBB_finish(cbb.get(), &der, &der_len)) {
  1037. return false;
  1038. }
  1039. bssl::UniquePtr<uint8_t> delete_der(der);
  1040. if (der_len != test.der_len ||
  1041. OPENSSL_memcmp(der, reinterpret_cast<const uint8_t *>(test.der),
  1042. der_len) != 0) {
  1043. fprintf(stderr, "Bad serialization.\n");
  1044. return false;
  1045. }
  1046. // |BN_parse_asn1_unsigned_buggy| parses all valid input.
  1047. CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
  1048. if (!BN_parse_asn1_unsigned_buggy(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
  1049. fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
  1050. return false;
  1051. }
  1052. if (BN_cmp(bn.get(), bn2.get()) != 0) {
  1053. fprintf(stderr, "Bad parse.\n");
  1054. return false;
  1055. }
  1056. }
  1057. for (const ASN1InvalidTest &test : kASN1InvalidTests) {
  1058. bssl::UniquePtr<BIGNUM> bn(BN_new());
  1059. if (!bn) {
  1060. return false;
  1061. }
  1062. CBS cbs;
  1063. CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
  1064. if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
  1065. fprintf(stderr, "Parsed invalid input.\n");
  1066. return false;
  1067. }
  1068. ERR_clear_error();
  1069. // All tests in kASN1InvalidTests are also rejected by
  1070. // |BN_parse_asn1_unsigned_buggy|.
  1071. CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
  1072. if (BN_parse_asn1_unsigned_buggy(&cbs, bn.get())) {
  1073. fprintf(stderr, "Parsed invalid input.\n");
  1074. return false;
  1075. }
  1076. ERR_clear_error();
  1077. }
  1078. for (const ASN1Test &test : kASN1BuggyTests) {
  1079. // These broken encodings are rejected by |BN_parse_asn1_unsigned|.
  1080. bssl::UniquePtr<BIGNUM> bn(BN_new());
  1081. if (!bn) {
  1082. return false;
  1083. }
  1084. CBS cbs;
  1085. CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
  1086. if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
  1087. fprintf(stderr, "Parsed invalid input.\n");
  1088. return false;
  1089. }
  1090. ERR_clear_error();
  1091. // However |BN_parse_asn1_unsigned_buggy| accepts them.
  1092. bssl::UniquePtr<BIGNUM> bn2 = ASCIIToBIGNUM(test.value_ascii);
  1093. if (!bn2) {
  1094. return false;
  1095. }
  1096. CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
  1097. if (!BN_parse_asn1_unsigned_buggy(&cbs, bn.get()) || CBS_len(&cbs) != 0) {
  1098. fprintf(stderr, "Parsing (invalid) ASN.1 INTEGER failed.\n");
  1099. return false;
  1100. }
  1101. if (BN_cmp(bn.get(), bn2.get()) != 0) {
  1102. fprintf(stderr, "\"Bad\" parse.\n");
  1103. return false;
  1104. }
  1105. }
  1106. // Serializing negative numbers is not supported.
  1107. bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM("-1");
  1108. if (!bn) {
  1109. return false;
  1110. }
  1111. bssl::ScopedCBB cbb;
  1112. if (!CBB_init(cbb.get(), 0) ||
  1113. BN_marshal_asn1(cbb.get(), bn.get())) {
  1114. fprintf(stderr, "Serialized negative number.\n");
  1115. return false;
  1116. }
  1117. ERR_clear_error();
  1118. return true;
  1119. }
  1120. static bool TestNegativeZero(BN_CTX *ctx) {
  1121. bssl::UniquePtr<BIGNUM> a(BN_new());
  1122. bssl::UniquePtr<BIGNUM> b(BN_new());
  1123. bssl::UniquePtr<BIGNUM> c(BN_new());
  1124. if (!a || !b || !c) {
  1125. return false;
  1126. }
  1127. // Test that BN_mul never gives negative zero.
  1128. if (!BN_set_word(a.get(), 1)) {
  1129. return false;
  1130. }
  1131. BN_set_negative(a.get(), 1);
  1132. BN_zero(b.get());
  1133. if (!BN_mul(c.get(), a.get(), b.get(), ctx)) {
  1134. return false;
  1135. }
  1136. if (!BN_is_zero(c.get()) || BN_is_negative(c.get())) {
  1137. fprintf(stderr, "Multiplication test failed.\n");
  1138. return false;
  1139. }
  1140. bssl::UniquePtr<BIGNUM> numerator(BN_new()), denominator(BN_new());
  1141. if (!numerator || !denominator) {
  1142. return false;
  1143. }
  1144. // Test that BN_div never gives negative zero in the quotient.
  1145. if (!BN_set_word(numerator.get(), 1) ||
  1146. !BN_set_word(denominator.get(), 2)) {
  1147. return false;
  1148. }
  1149. BN_set_negative(numerator.get(), 1);
  1150. if (!BN_div(a.get(), b.get(), numerator.get(), denominator.get(), ctx)) {
  1151. return false;
  1152. }
  1153. if (!BN_is_zero(a.get()) || BN_is_negative(a.get())) {
  1154. fprintf(stderr, "Incorrect quotient.\n");
  1155. return false;
  1156. }
  1157. // Test that BN_div never gives negative zero in the remainder.
  1158. if (!BN_set_word(denominator.get(), 1)) {
  1159. return false;
  1160. }
  1161. if (!BN_div(a.get(), b.get(), numerator.get(), denominator.get(), ctx)) {
  1162. return false;
  1163. }
  1164. if (!BN_is_zero(b.get()) || BN_is_negative(b.get())) {
  1165. fprintf(stderr, "Incorrect remainder.\n");
  1166. return false;
  1167. }
  1168. // Test that BN_set_negative will not produce a negative zero.
  1169. BN_zero(a.get());
  1170. BN_set_negative(a.get(), 1);
  1171. if (BN_is_negative(a.get())) {
  1172. fprintf(stderr, "BN_set_negative produced a negative zero.\n");
  1173. return false;
  1174. }
  1175. // Test that forcibly creating a negative zero does not break |BN_bn2hex| or
  1176. // |BN_bn2dec|.
  1177. a->neg = 1;
  1178. bssl::UniquePtr<char> dec(BN_bn2dec(a.get()));
  1179. bssl::UniquePtr<char> hex(BN_bn2hex(a.get()));
  1180. if (!dec || !hex ||
  1181. strcmp(dec.get(), "-0") != 0 ||
  1182. strcmp(hex.get(), "-0") != 0) {
  1183. fprintf(stderr, "BN_bn2dec or BN_bn2hex failed with negative zero.\n");
  1184. return false;
  1185. }
  1186. // Test that |BN_rshift| and |BN_rshift1| will not produce a negative zero.
  1187. if (!BN_set_word(a.get(), 1)) {
  1188. return false;
  1189. }
  1190. BN_set_negative(a.get(), 1);
  1191. if (!BN_rshift(b.get(), a.get(), 1) ||
  1192. !BN_rshift1(c.get(), a.get())) {
  1193. return false;
  1194. }
  1195. if (!BN_is_zero(b.get()) || BN_is_negative(b.get())) {
  1196. fprintf(stderr, "BN_rshift(-1, 1) produced the wrong result.\n");
  1197. return false;
  1198. }
  1199. if (!BN_is_zero(c.get()) || BN_is_negative(c.get())) {
  1200. fprintf(stderr, "BN_rshift1(-1) produced the wrong result.\n");
  1201. return false;
  1202. }
  1203. // Test that |BN_div_word| will not produce a negative zero.
  1204. if (BN_div_word(a.get(), 2) == (BN_ULONG)-1) {
  1205. return false;
  1206. }
  1207. if (!BN_is_zero(a.get()) || BN_is_negative(a.get())) {
  1208. fprintf(stderr, "BN_div_word(-1, 2) produced the wrong result.\n");
  1209. return false;
  1210. }
  1211. return true;
  1212. }
  1213. static bool TestBadModulus(BN_CTX *ctx) {
  1214. bssl::UniquePtr<BIGNUM> a(BN_new());
  1215. bssl::UniquePtr<BIGNUM> b(BN_new());
  1216. bssl::UniquePtr<BIGNUM> zero(BN_new());
  1217. bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
  1218. if (!a || !b || !zero || !mont) {
  1219. return false;
  1220. }
  1221. BN_zero(zero.get());
  1222. if (BN_div(a.get(), b.get(), BN_value_one(), zero.get(), ctx)) {
  1223. fprintf(stderr, "Division by zero unexpectedly succeeded.\n");
  1224. return false;
  1225. }
  1226. ERR_clear_error();
  1227. if (BN_mod_mul(a.get(), BN_value_one(), BN_value_one(), zero.get(), ctx)) {
  1228. fprintf(stderr, "BN_mod_mul with zero modulus unexpectedly succeeded.\n");
  1229. return false;
  1230. }
  1231. ERR_clear_error();
  1232. if (BN_mod_exp(a.get(), BN_value_one(), BN_value_one(), zero.get(), ctx)) {
  1233. fprintf(stderr, "BN_mod_exp with zero modulus unexpectedly succeeded.\n");
  1234. return 0;
  1235. }
  1236. ERR_clear_error();
  1237. if (BN_mod_exp_mont(a.get(), BN_value_one(), BN_value_one(), zero.get(), ctx,
  1238. NULL)) {
  1239. fprintf(stderr,
  1240. "BN_mod_exp_mont with zero modulus unexpectedly succeeded.\n");
  1241. return 0;
  1242. }
  1243. ERR_clear_error();
  1244. if (BN_mod_exp_mont_consttime(a.get(), BN_value_one(), BN_value_one(),
  1245. zero.get(), ctx, nullptr)) {
  1246. fprintf(stderr,
  1247. "BN_mod_exp_mont_consttime with zero modulus unexpectedly "
  1248. "succeeded.\n");
  1249. return 0;
  1250. }
  1251. ERR_clear_error();
  1252. if (BN_MONT_CTX_set(mont.get(), zero.get(), ctx)) {
  1253. fprintf(stderr,
  1254. "BN_MONT_CTX_set unexpectedly succeeded for zero modulus.\n");
  1255. return false;
  1256. }
  1257. ERR_clear_error();
  1258. // Some operations also may not be used with an even modulus.
  1259. if (!BN_set_word(b.get(), 16)) {
  1260. return false;
  1261. }
  1262. if (BN_MONT_CTX_set(mont.get(), b.get(), ctx)) {
  1263. fprintf(stderr,
  1264. "BN_MONT_CTX_set unexpectedly succeeded for even modulus.\n");
  1265. return false;
  1266. }
  1267. ERR_clear_error();
  1268. if (BN_mod_exp_mont(a.get(), BN_value_one(), BN_value_one(), b.get(), ctx,
  1269. NULL)) {
  1270. fprintf(stderr,
  1271. "BN_mod_exp_mont with even modulus unexpectedly succeeded.\n");
  1272. return 0;
  1273. }
  1274. ERR_clear_error();
  1275. if (BN_mod_exp_mont_consttime(a.get(), BN_value_one(), BN_value_one(),
  1276. b.get(), ctx, nullptr)) {
  1277. fprintf(stderr,
  1278. "BN_mod_exp_mont_consttime with even modulus unexpectedly "
  1279. "succeeded.\n");
  1280. return 0;
  1281. }
  1282. ERR_clear_error();
  1283. return true;
  1284. }
  1285. // TestExpModZero tests that 1**0 mod 1 == 0.
  1286. static bool TestExpModZero() {
  1287. bssl::UniquePtr<BIGNUM> zero(BN_new()), a(BN_new()), r(BN_new());
  1288. if (!zero || !a || !r ||
  1289. !BN_rand(a.get(), 1024, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
  1290. return false;
  1291. }
  1292. BN_zero(zero.get());
  1293. if (!BN_mod_exp(r.get(), a.get(), zero.get(), BN_value_one(), nullptr) ||
  1294. !BN_is_zero(r.get()) ||
  1295. !BN_mod_exp_mont(r.get(), a.get(), zero.get(), BN_value_one(), nullptr,
  1296. nullptr) ||
  1297. !BN_is_zero(r.get()) ||
  1298. !BN_mod_exp_mont_consttime(r.get(), a.get(), zero.get(), BN_value_one(),
  1299. nullptr, nullptr) ||
  1300. !BN_is_zero(r.get()) ||
  1301. !BN_mod_exp_mont_word(r.get(), 42, zero.get(), BN_value_one(), nullptr,
  1302. nullptr) ||
  1303. !BN_is_zero(r.get())) {
  1304. return false;
  1305. }
  1306. return true;
  1307. }
  1308. static bool TestSmallPrime(BN_CTX *ctx) {
  1309. static const unsigned kBits = 10;
  1310. bssl::UniquePtr<BIGNUM> r(BN_new());
  1311. if (!r || !BN_generate_prime_ex(r.get(), static_cast<int>(kBits), 0, NULL,
  1312. NULL, NULL)) {
  1313. return false;
  1314. }
  1315. if (BN_num_bits(r.get()) != kBits) {
  1316. fprintf(stderr, "Expected %u bit prime, got %u bit number\n", kBits,
  1317. BN_num_bits(r.get()));
  1318. return false;
  1319. }
  1320. return true;
  1321. }
  1322. static bool TestCmpWord() {
  1323. static const BN_ULONG kMaxWord = (BN_ULONG)-1;
  1324. bssl::UniquePtr<BIGNUM> r(BN_new());
  1325. if (!r ||
  1326. !BN_set_word(r.get(), 0)) {
  1327. return false;
  1328. }
  1329. if (BN_cmp_word(r.get(), 0) != 0 ||
  1330. BN_cmp_word(r.get(), 1) >= 0 ||
  1331. BN_cmp_word(r.get(), kMaxWord) >= 0) {
  1332. fprintf(stderr, "BN_cmp_word compared against 0 incorrectly.\n");
  1333. return false;
  1334. }
  1335. if (!BN_set_word(r.get(), 100)) {
  1336. return false;
  1337. }
  1338. if (BN_cmp_word(r.get(), 0) <= 0 ||
  1339. BN_cmp_word(r.get(), 99) <= 0 ||
  1340. BN_cmp_word(r.get(), 100) != 0 ||
  1341. BN_cmp_word(r.get(), 101) >= 0 ||
  1342. BN_cmp_word(r.get(), kMaxWord) >= 0) {
  1343. fprintf(stderr, "BN_cmp_word compared against 100 incorrectly.\n");
  1344. return false;
  1345. }
  1346. BN_set_negative(r.get(), 1);
  1347. if (BN_cmp_word(r.get(), 0) >= 0 ||
  1348. BN_cmp_word(r.get(), 100) >= 0 ||
  1349. BN_cmp_word(r.get(), kMaxWord) >= 0) {
  1350. fprintf(stderr, "BN_cmp_word compared against -100 incorrectly.\n");
  1351. return false;
  1352. }
  1353. if (!BN_set_word(r.get(), kMaxWord)) {
  1354. return false;
  1355. }
  1356. if (BN_cmp_word(r.get(), 0) <= 0 ||
  1357. BN_cmp_word(r.get(), kMaxWord - 1) <= 0 ||
  1358. BN_cmp_word(r.get(), kMaxWord) != 0) {
  1359. fprintf(stderr, "BN_cmp_word compared against kMaxWord incorrectly.\n");
  1360. return false;
  1361. }
  1362. if (!BN_add(r.get(), r.get(), BN_value_one())) {
  1363. return false;
  1364. }
  1365. if (BN_cmp_word(r.get(), 0) <= 0 ||
  1366. BN_cmp_word(r.get(), kMaxWord) <= 0) {
  1367. fprintf(stderr, "BN_cmp_word compared against kMaxWord + 1 incorrectly.\n");
  1368. return false;
  1369. }
  1370. BN_set_negative(r.get(), 1);
  1371. if (BN_cmp_word(r.get(), 0) >= 0 ||
  1372. BN_cmp_word(r.get(), kMaxWord) >= 0) {
  1373. fprintf(stderr,
  1374. "BN_cmp_word compared against -kMaxWord - 1 incorrectly.\n");
  1375. return false;
  1376. }
  1377. return true;
  1378. }
  1379. static bool TestBN2Dec() {
  1380. static const char *kBN2DecTests[] = {
  1381. "0",
  1382. "1",
  1383. "-1",
  1384. "100",
  1385. "-100",
  1386. "123456789012345678901234567890",
  1387. "-123456789012345678901234567890",
  1388. "123456789012345678901234567890123456789012345678901234567890",
  1389. "-123456789012345678901234567890123456789012345678901234567890",
  1390. };
  1391. for (const char *test : kBN2DecTests) {
  1392. bssl::UniquePtr<BIGNUM> bn;
  1393. int ret = DecimalToBIGNUM(&bn, test);
  1394. if (ret == 0) {
  1395. return false;
  1396. }
  1397. bssl::UniquePtr<char> dec(BN_bn2dec(bn.get()));
  1398. if (!dec) {
  1399. fprintf(stderr, "BN_bn2dec failed on %s.\n", test);
  1400. return false;
  1401. }
  1402. if (strcmp(dec.get(), test) != 0) {
  1403. fprintf(stderr, "BN_bn2dec gave %s, wanted %s.\n", dec.get(), test);
  1404. return false;
  1405. }
  1406. }
  1407. return true;
  1408. }
  1409. static bool TestBNSetGetU64() {
  1410. static const struct {
  1411. const char *hex;
  1412. uint64_t value;
  1413. } kU64Tests[] = {
  1414. {"0", UINT64_C(0x0)},
  1415. {"1", UINT64_C(0x1)},
  1416. {"ffffffff", UINT64_C(0xffffffff)},
  1417. {"100000000", UINT64_C(0x100000000)},
  1418. {"ffffffffffffffff", UINT64_C(0xffffffffffffffff)},
  1419. };
  1420. for (const auto& test : kU64Tests) {
  1421. bssl::UniquePtr<BIGNUM> bn(BN_new()), expected;
  1422. if (!bn ||
  1423. !BN_set_u64(bn.get(), test.value) ||
  1424. !HexToBIGNUM(&expected, test.hex) ||
  1425. BN_cmp(bn.get(), expected.get()) != 0) {
  1426. fprintf(stderr, "BN_set_u64 test failed for 0x%s.\n", test.hex);
  1427. ERR_print_errors_fp(stderr);
  1428. return false;
  1429. }
  1430. uint64_t tmp;
  1431. if (!BN_get_u64(bn.get(), &tmp) || tmp != test.value) {
  1432. fprintf(stderr, "BN_get_u64 test failed for 0x%s.\n", test.hex);
  1433. return false;
  1434. }
  1435. BN_set_negative(bn.get(), 1);
  1436. if (!BN_get_u64(bn.get(), &tmp) || tmp != test.value) {
  1437. fprintf(stderr, "BN_get_u64 test failed for -0x%s.\n", test.hex);
  1438. return false;
  1439. }
  1440. }
  1441. // Test that BN_get_u64 fails on large numbers.
  1442. bssl::UniquePtr<BIGNUM> bn(BN_new());
  1443. if (!BN_lshift(bn.get(), BN_value_one(), 64)) {
  1444. return false;
  1445. }
  1446. uint64_t tmp;
  1447. if (BN_get_u64(bn.get(), &tmp)) {
  1448. fprintf(stderr, "BN_get_u64 of 2^64 unexpectedly succeeded.\n");
  1449. return false;
  1450. }
  1451. BN_set_negative(bn.get(), 1);
  1452. if (BN_get_u64(bn.get(), &tmp)) {
  1453. fprintf(stderr, "BN_get_u64 of -2^64 unexpectedly succeeded.\n");
  1454. return false;
  1455. }
  1456. return true;
  1457. }
  1458. static bool TestBNPow2(BN_CTX *ctx) {
  1459. bssl::UniquePtr<BIGNUM>
  1460. power_of_two(BN_new()),
  1461. random(BN_new()),
  1462. expected(BN_new()),
  1463. actual(BN_new());
  1464. if (!power_of_two.get() ||
  1465. !random.get() ||
  1466. !expected.get() ||
  1467. !actual.get()) {
  1468. return false;
  1469. }
  1470. // Choose an exponent.
  1471. for (size_t e = 3; e < 512; e += 11) {
  1472. // Choose a bit length for our randoms.
  1473. for (int len = 3; len < 512; len += 23) {
  1474. // Set power_of_two = 2^e.
  1475. if (!BN_lshift(power_of_two.get(), BN_value_one(), (int) e)) {
  1476. fprintf(stderr, "Failed to shiftl.\n");
  1477. return false;
  1478. }
  1479. // Test BN_is_pow2 on power_of_two.
  1480. if (!BN_is_pow2(power_of_two.get())) {
  1481. fprintf(stderr, "BN_is_pow2 returned false for a power of two.\n");
  1482. hexdump(stderr, "Arg: ", power_of_two->d,
  1483. power_of_two->top * sizeof(BN_ULONG));
  1484. return false;
  1485. }
  1486. // Pick a large random value, ensuring it isn't a power of two.
  1487. if (!BN_rand(random.get(), len, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) {
  1488. fprintf(stderr, "Failed to generate random in TestBNPow2.\n");
  1489. return false;
  1490. }
  1491. // Test BN_is_pow2 on |r|.
  1492. if (BN_is_pow2(random.get())) {
  1493. fprintf(stderr, "BN_is_pow2 returned true for a non-power of two.\n");
  1494. hexdump(stderr, "Arg: ", random->d, random->top * sizeof(BN_ULONG));
  1495. return false;
  1496. }
  1497. // Test BN_mod_pow2 on |r|.
  1498. if (!BN_mod(expected.get(), random.get(), power_of_two.get(), ctx) ||
  1499. !BN_mod_pow2(actual.get(), random.get(), e) ||
  1500. BN_cmp(actual.get(), expected.get())) {
  1501. fprintf(stderr, "BN_mod_pow2 returned the wrong value:\n");
  1502. hexdump(stderr, "Expected: ", expected->d,
  1503. expected->top * sizeof(BN_ULONG));
  1504. hexdump(stderr, "Got: ", actual->d,
  1505. actual->top * sizeof(BN_ULONG));
  1506. return false;
  1507. }
  1508. // Test BN_nnmod_pow2 on |r|.
  1509. if (!BN_nnmod(expected.get(), random.get(), power_of_two.get(), ctx) ||
  1510. !BN_nnmod_pow2(actual.get(), random.get(), e) ||
  1511. BN_cmp(actual.get(), expected.get())) {
  1512. fprintf(stderr, "BN_nnmod_pow2 failed on positive input:\n");
  1513. hexdump(stderr, "Expected: ", expected->d,
  1514. expected->top * sizeof(BN_ULONG));
  1515. hexdump(stderr, "Got: ", actual->d,
  1516. actual->top * sizeof(BN_ULONG));
  1517. return false;
  1518. }
  1519. // Test BN_nnmod_pow2 on -|r|.
  1520. BN_set_negative(random.get(), 1);
  1521. if (!BN_nnmod(expected.get(), random.get(), power_of_two.get(), ctx) ||
  1522. !BN_nnmod_pow2(actual.get(), random.get(), e) ||
  1523. BN_cmp(actual.get(), expected.get())) {
  1524. fprintf(stderr, "BN_nnmod_pow2 failed on negative input:\n");
  1525. hexdump(stderr, "Expected: ", expected->d,
  1526. expected->top * sizeof(BN_ULONG));
  1527. hexdump(stderr, "Got: ", actual->d,
  1528. actual->top * sizeof(BN_ULONG));
  1529. return false;
  1530. }
  1531. }
  1532. }
  1533. return true;
  1534. }
  1535. int main(int argc, char *argv[]) {
  1536. CRYPTO_library_init();
  1537. if (argc != 2) {
  1538. fprintf(stderr, "%s TEST_FILE\n", argv[0]);
  1539. return 1;
  1540. }
  1541. bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
  1542. if (!ctx) {
  1543. return 1;
  1544. }
  1545. if (!TestBN2BinPadded(ctx.get()) ||
  1546. !TestDec2BN(ctx.get()) ||
  1547. !TestHex2BN(ctx.get()) ||
  1548. !TestASC2BN(ctx.get()) ||
  1549. !TestLittleEndian() ||
  1550. !TestMPI() ||
  1551. !TestRand() ||
  1552. !TestASN1() ||
  1553. !TestNegativeZero(ctx.get()) ||
  1554. !TestBadModulus(ctx.get()) ||
  1555. !TestExpModZero() ||
  1556. !TestSmallPrime(ctx.get()) ||
  1557. !TestCmpWord() ||
  1558. !TestBN2Dec() ||
  1559. !TestBNSetGetU64() ||
  1560. !TestBNPow2(ctx.get())) {
  1561. return 1;
  1562. }
  1563. return FileTestMain(RunTest, ctx.get(), argv[1]);
  1564. }