]>
Commit | Line | Data |
---|---|---|
440e5d80 | 1 | /* |
fe16ae5f | 2 | * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. |
d02b48c6 | 3 | * |
909f1a2e | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
440e5d80 RS |
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 | |
d02b48c6 | 8 | */ |
8d1ebff4 RS |
9 | #include <assert.h> |
10 | #include <errno.h> | |
d02b48c6 | 11 | #include <stdio.h> |
d02b48c6 | 12 | #include <string.h> |
08073700 RB |
13 | #ifdef __TANDEM |
14 | # include <strings.h> /* strcasecmp */ | |
15 | #endif | |
8d1ebff4 | 16 | #include <ctype.h> |
17e3dd1c | 17 | |
ec577822 | 18 | #include <openssl/bn.h> |
8d1ebff4 | 19 | #include <openssl/crypto.h> |
ec577822 | 20 | #include <openssl/err.h> |
8d1ebff4 | 21 | #include <openssl/rand.h> |
2b1aa198 RL |
22 | #include "internal/nelem.h" |
23 | #include "internal/numbers.h" | |
8d1ebff4 | 24 | #include "testutil.h" |
d02b48c6 | 25 | |
2b1aa198 RL |
26 | #ifdef OPENSSL_SYS_WINDOWS |
27 | # define strcasecmp _stricmp | |
28 | #endif | |
8927c278 | 29 | |
8d1ebff4 RS |
30 | /* |
31 | * Things in boring, not in openssl. TODO we should add them. | |
32 | */ | |
33 | #define HAVE_BN_PADDED 0 | |
34 | #define HAVE_BN_SQRT 0 | |
0f113f3e | 35 | |
8d1ebff4 RS |
36 | typedef struct filetest_st { |
37 | const char *name; | |
38 | int (*func)(STANZA *s); | |
39 | } FILETEST; | |
0f113f3e | 40 | |
8d1ebff4 RS |
41 | typedef struct mpitest_st { |
42 | const char *base10; | |
43 | const char *mpi; | |
44 | size_t mpi_len; | |
45 | } MPITEST; | |
0f113f3e | 46 | |
8d1ebff4 RS |
47 | static const int NUM0 = 100; /* number of tests */ |
48 | static const int NUM1 = 50; /* additional tests for some functions */ | |
8d1ebff4 | 49 | static BN_CTX *ctx; |
0f113f3e | 50 | |
30bea14b RS |
51 | /* |
52 | * Polynomial coefficients used in GFM tests. | |
53 | */ | |
ed5c7ea2 | 54 | #ifndef OPENSSL_NO_EC2M |
30bea14b RS |
55 | static int p0[] = { 163, 7, 6, 3, 0, -1 }; |
56 | static int p1[] = { 193, 15, 0, -1 }; | |
ed5c7ea2 | 57 | #endif |
0f113f3e | 58 | |
8d1ebff4 RS |
59 | /* |
60 | * Look for |key| in the stanza and return it or NULL if not found. | |
61 | */ | |
62 | static const char *findattr(STANZA *s, const char *key) | |
63 | { | |
64 | int i = s->numpairs; | |
65 | PAIR *pp = s->pairs; | |
0f113f3e | 66 | |
8d1ebff4 RS |
67 | for ( ; --i >= 0; pp++) |
68 | if (strcasecmp(pp->key, key) == 0) | |
69 | return pp->value; | |
70 | return NULL; | |
71 | } | |
0f113f3e | 72 | |
4483fbae F |
73 | /* |
74 | * Parse BIGNUM from sparse hex-strings, return |BN_hex2bn| result. | |
75 | */ | |
76 | static int parse_bigBN(BIGNUM **out, const char *bn_strings[]) | |
77 | { | |
78 | char *bigstring = glue_strings(bn_strings, NULL); | |
79 | int ret = BN_hex2bn(out, bigstring); | |
80 | ||
81 | OPENSSL_free(bigstring); | |
82 | return ret; | |
83 | } | |
84 | ||
8d1ebff4 RS |
85 | /* |
86 | * Parse BIGNUM, return number of bytes parsed. | |
87 | */ | |
88 | static int parseBN(BIGNUM **out, const char *in) | |
89 | { | |
90 | *out = NULL; | |
91 | return BN_hex2bn(out, in); | |
92 | } | |
0f113f3e | 93 | |
8d1ebff4 RS |
94 | static int parsedecBN(BIGNUM **out, const char *in) |
95 | { | |
96 | *out = NULL; | |
97 | return BN_dec2bn(out, in); | |
98 | } | |
96a4c31b | 99 | |
8d1ebff4 RS |
100 | static BIGNUM *getBN(STANZA *s, const char *attribute) |
101 | { | |
102 | const char *hex; | |
103 | BIGNUM *ret = NULL; | |
8ff70f33 | 104 | |
8d1ebff4 | 105 | if ((hex = findattr(s, attribute)) == NULL) { |
ae269dd8 | 106 | TEST_error("%s:%d: Can't find %s", s->test_file, s->start, attribute); |
8d1ebff4 RS |
107 | return NULL; |
108 | } | |
0f113f3e | 109 | |
8d1ebff4 | 110 | if (parseBN(&ret, hex) != (int)strlen(hex)) { |
30bea14b | 111 | TEST_error("Could not decode '%s'", hex); |
8d1ebff4 RS |
112 | return NULL; |
113 | } | |
114 | return ret; | |
115 | } | |
0f113f3e | 116 | |
8d1ebff4 RS |
117 | static int getint(STANZA *s, int *out, const char *attribute) |
118 | { | |
30bea14b | 119 | BIGNUM *ret; |
8d1ebff4 RS |
120 | BN_ULONG word; |
121 | int st = 0; | |
0f113f3e | 122 | |
30bea14b RS |
123 | if (!TEST_ptr(ret = getBN(s, attribute)) |
124 | || !TEST_ulong_le(word = BN_get_word(ret), INT_MAX)) | |
0f113f3e | 125 | goto err; |
0f113f3e | 126 | |
8d1ebff4 RS |
127 | *out = (int)word; |
128 | st = 1; | |
fe16ae5f | 129 | err: |
8d1ebff4 RS |
130 | BN_free(ret); |
131 | return st; | |
132 | } | |
0f113f3e | 133 | |
8d1ebff4 RS |
134 | static int equalBN(const char *op, const BIGNUM *expected, const BIGNUM *actual) |
135 | { | |
8d1ebff4 RS |
136 | if (BN_cmp(expected, actual) == 0) |
137 | return 1; | |
0f113f3e | 138 | |
dc352c19 P |
139 | TEST_error("unexpected %s value", op); |
140 | TEST_BN_eq(expected, actual); | |
8d1ebff4 | 141 | return 0; |
0f113f3e | 142 | } |
d02b48c6 | 143 | |
8d1ebff4 RS |
144 | /* |
145 | * Return a "random" flag for if a BN should be negated. | |
146 | */ | |
147 | static int rand_neg(void) | |
148 | { | |
149 | static unsigned int neg = 0; | |
150 | static int sign[8] = { 0, 0, 0, 1, 1, 0, 1, 1 }; | |
0f113f3e | 151 | |
8d1ebff4 | 152 | return sign[(neg++) % 8]; |
0f113f3e | 153 | } |
d02b48c6 | 154 | |
9e5b50b5 BB |
155 | static int test_swap(void) |
156 | { | |
157 | BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL; | |
158 | int top, cond, st = 0; | |
159 | ||
160 | if (!TEST_ptr(a = BN_new()) | |
161 | || !TEST_ptr(b = BN_new()) | |
162 | || !TEST_ptr(c = BN_new()) | |
163 | || !TEST_ptr(d = BN_new())) | |
164 | goto err; | |
165 | ||
e2f50811 SL |
166 | if (!(TEST_true(BN_bntest_rand(a, 1024, 1, 0)) |
167 | && TEST_true(BN_bntest_rand(b, 1024, 1, 0)) | |
168 | && TEST_ptr(BN_copy(c, a)) | |
169 | && TEST_ptr(BN_copy(d, b)))) | |
170 | goto err; | |
fe16ae5f | 171 | top = BN_num_bits(a) / BN_BITS2; |
9e5b50b5 BB |
172 | |
173 | /* regular swap */ | |
174 | BN_swap(a, b); | |
175 | if (!equalBN("swap", a, d) | |
176 | || !equalBN("swap", b, c)) | |
177 | goto err; | |
178 | ||
179 | /* conditional swap: true */ | |
180 | cond = 1; | |
181 | BN_consttime_swap(cond, a, b, top); | |
182 | if (!equalBN("cswap true", a, c) | |
183 | || !equalBN("cswap true", b, d)) | |
184 | goto err; | |
185 | ||
186 | /* conditional swap: false */ | |
187 | cond = 0; | |
188 | BN_consttime_swap(cond, a, b, top); | |
189 | if (!equalBN("cswap false", a, c) | |
190 | || !equalBN("cswap false", b, d)) | |
191 | goto err; | |
192 | ||
193 | /* same tests but checking flag swap */ | |
194 | BN_set_flags(a, BN_FLG_CONSTTIME); | |
195 | ||
196 | BN_swap(a, b); | |
197 | if (!equalBN("swap, flags", a, d) | |
198 | || !equalBN("swap, flags", b, c) | |
199 | || !TEST_true(BN_get_flags(b, BN_FLG_CONSTTIME)) | |
200 | || !TEST_false(BN_get_flags(a, BN_FLG_CONSTTIME))) | |
201 | goto err; | |
202 | ||
203 | cond = 1; | |
204 | BN_consttime_swap(cond, a, b, top); | |
205 | if (!equalBN("cswap true, flags", a, c) | |
206 | || !equalBN("cswap true, flags", b, d) | |
207 | || !TEST_true(BN_get_flags(a, BN_FLG_CONSTTIME)) | |
208 | || !TEST_false(BN_get_flags(b, BN_FLG_CONSTTIME))) | |
209 | goto err; | |
210 | ||
211 | cond = 0; | |
212 | BN_consttime_swap(cond, a, b, top); | |
213 | if (!equalBN("cswap false, flags", a, c) | |
214 | || !equalBN("cswap false, flags", b, d) | |
215 | || !TEST_true(BN_get_flags(a, BN_FLG_CONSTTIME)) | |
216 | || !TEST_false(BN_get_flags(b, BN_FLG_CONSTTIME))) | |
217 | goto err; | |
218 | ||
219 | st = 1; | |
220 | err: | |
221 | BN_free(a); | |
222 | BN_free(b); | |
223 | BN_free(c); | |
224 | BN_free(d); | |
225 | return st; | |
226 | } | |
227 | ||
31a80694 | 228 | static int test_sub(void) |
0f113f3e | 229 | { |
30bea14b RS |
230 | BIGNUM *a = NULL, *b = NULL, *c = NULL; |
231 | int i, st = 0; | |
0f113f3e | 232 | |
30bea14b RS |
233 | if (!TEST_ptr(a = BN_new()) |
234 | || !TEST_ptr(b = BN_new()) | |
235 | || !TEST_ptr(c = BN_new())) | |
236 | goto err; | |
0f113f3e | 237 | |
8d1ebff4 RS |
238 | for (i = 0; i < NUM0 + NUM1; i++) { |
239 | if (i < NUM1) { | |
e2f50811 SL |
240 | if (!(TEST_true(BN_bntest_rand(a, 512, 0, 0))) |
241 | && TEST_ptr(BN_copy(b, a)) | |
242 | && TEST_int_ne(BN_set_bit(a, i), 0) | |
243 | && TEST_true(BN_add_word(b, i))) | |
30bea14b | 244 | goto err; |
0f113f3e | 245 | } else { |
e2f50811 SL |
246 | if (!TEST_true(BN_bntest_rand(b, 400 + i - NUM1, 0, 0))) |
247 | goto err; | |
2b1aa198 RL |
248 | BN_set_negative(a, rand_neg()); |
249 | BN_set_negative(b, rand_neg()); | |
0f113f3e | 250 | } |
e2f50811 SL |
251 | if (!(TEST_true(BN_sub(c, a, b)) |
252 | && TEST_true(BN_add(c, c, b)) | |
253 | && TEST_true(BN_sub(c, c, a)) | |
254 | && TEST_BN_eq_zero(c))) | |
30bea14b | 255 | goto err; |
0f113f3e | 256 | } |
30bea14b | 257 | st = 1; |
fe16ae5f | 258 | err: |
0f113f3e MC |
259 | BN_free(a); |
260 | BN_free(b); | |
261 | BN_free(c); | |
30bea14b | 262 | return st; |
0f113f3e | 263 | } |
8169dd73 | 264 | |
31a80694 | 265 | static int test_div_recip(void) |
0f113f3e | 266 | { |
30bea14b RS |
267 | BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL; |
268 | BN_RECP_CTX *recp = NULL; | |
269 | int st = 0, i; | |
0f113f3e | 270 | |
30bea14b RS |
271 | if (!TEST_ptr(a = BN_new()) |
272 | || !TEST_ptr(b = BN_new()) | |
273 | || !TEST_ptr(c = BN_new()) | |
274 | || !TEST_ptr(d = BN_new()) | |
275 | || !TEST_ptr(e = BN_new()) | |
276 | || !TEST_ptr(recp = BN_RECP_CTX_new())) | |
277 | goto err; | |
0f113f3e | 278 | |
8d1ebff4 RS |
279 | for (i = 0; i < NUM0 + NUM1; i++) { |
280 | if (i < NUM1) { | |
e2f50811 SL |
281 | if (!(TEST_true(BN_bntest_rand(a, 400, 0, 0)) |
282 | && TEST_ptr(BN_copy(b, a)) | |
283 | && TEST_true(BN_lshift(a, a, i)) | |
284 | && TEST_true(BN_add_word(a, i)))) | |
285 | goto err; | |
286 | } else { | |
287 | if (!(TEST_true(BN_bntest_rand(b, 50 + 3 * (i - NUM1), 0, 0)))) | |
288 | goto err; | |
289 | } | |
2b1aa198 RL |
290 | BN_set_negative(a, rand_neg()); |
291 | BN_set_negative(b, rand_neg()); | |
e2f50811 SL |
292 | if (!(TEST_true(BN_RECP_CTX_set(recp, b, ctx)) |
293 | && TEST_true(BN_div_recp(d, c, a, recp, ctx)) | |
294 | && TEST_true(BN_mul(e, d, b, ctx)) | |
295 | && TEST_true(BN_add(d, e, c)) | |
296 | && TEST_true(BN_sub(d, d, a)) | |
297 | && TEST_BN_eq_zero(d))) | |
30bea14b | 298 | goto err; |
0f113f3e | 299 | } |
30bea14b | 300 | st = 1; |
fe16ae5f | 301 | err: |
0f113f3e MC |
302 | BN_free(a); |
303 | BN_free(b); | |
304 | BN_free(c); | |
305 | BN_free(d); | |
306 | BN_free(e); | |
307 | BN_RECP_CTX_free(recp); | |
30bea14b | 308 | return st; |
0f113f3e | 309 | } |
d02b48c6 | 310 | |
31a80694 | 311 | static int test_mod(void) |
0f113f3e | 312 | { |
30bea14b RS |
313 | BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL; |
314 | int st = 0, i; | |
0f113f3e | 315 | |
30bea14b RS |
316 | if (!TEST_ptr(a = BN_new()) |
317 | || !TEST_ptr(b = BN_new()) | |
318 | || !TEST_ptr(c = BN_new()) | |
319 | || !TEST_ptr(d = BN_new()) | |
320 | || !TEST_ptr(e = BN_new())) | |
321 | goto err; | |
0f113f3e | 322 | |
e2f50811 SL |
323 | if (!(TEST_true(BN_bntest_rand(a, 1024, 0, 0)))) |
324 | goto err; | |
8d1ebff4 | 325 | for (i = 0; i < NUM0; i++) { |
e2f50811 SL |
326 | if (!(TEST_true(BN_bntest_rand(b, 450 + i * 10, 0, 0)))) |
327 | goto err; | |
2b1aa198 RL |
328 | BN_set_negative(a, rand_neg()); |
329 | BN_set_negative(b, rand_neg()); | |
e2f50811 SL |
330 | if (!(TEST_true(BN_mod(c, a, b, ctx)) |
331 | && TEST_true(BN_div(d, e, a, b, ctx)) | |
332 | && TEST_true(BN_sub(e, e, c)) | |
333 | && TEST_BN_eq_zero(e))) | |
30bea14b | 334 | goto err; |
0f113f3e | 335 | } |
30bea14b | 336 | st = 1; |
fe16ae5f | 337 | err: |
0f113f3e MC |
338 | BN_free(a); |
339 | BN_free(b); | |
340 | BN_free(c); | |
341 | BN_free(d); | |
342 | BN_free(e); | |
30bea14b | 343 | return st; |
0f113f3e | 344 | } |
d02b48c6 | 345 | |
26a39fa9 RS |
346 | static const char *bn1strings[] = { |
347 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
348 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
349 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
350 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
351 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
352 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
353 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
354 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF00", | |
355 | "0000000000000000000000000000000000000000000000000000000000000000", | |
356 | "0000000000000000000000000000000000000000000000000000000000000000", | |
357 | "0000000000000000000000000000000000000000000000000000000000000000", | |
358 | "0000000000000000000000000000000000000000000000000000000000000000", | |
359 | "0000000000000000000000000000000000000000000000000000000000000000", | |
360 | "0000000000000000000000000000000000000000000000000000000000000000", | |
361 | "0000000000000000000000000000000000000000000000000000000000000000", | |
362 | "00000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF", | |
363 | NULL | |
364 | }; | |
365 | ||
366 | static const char *bn2strings[] = { | |
367 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
368 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
369 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
370 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
371 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
372 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
373 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
374 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF0000000000", | |
375 | "0000000000000000000000000000000000000000000000000000000000000000", | |
376 | "0000000000000000000000000000000000000000000000000000000000000000", | |
377 | "0000000000000000000000000000000000000000000000000000000000000000", | |
378 | "0000000000000000000000000000000000000000000000000000000000000000", | |
379 | "0000000000000000000000000000000000000000000000000000000000000000", | |
380 | "0000000000000000000000000000000000000000000000000000000000000000", | |
381 | "0000000000000000000000000000000000000000000000000000000000000000", | |
382 | "000000000000000000000000000000000000000000FFFFFFFFFFFFFF00000000", | |
383 | NULL | |
384 | }; | |
385 | ||
8d1ebff4 RS |
386 | /* |
387 | * Test constant-time modular exponentiation with 1024-bit inputs, which on | |
388 | * x86_64 cause a different code branch to be taken. | |
389 | */ | |
31a80694 | 390 | static int test_modexp_mont5(void) |
0f113f3e | 391 | { |
30bea14b RS |
392 | BIGNUM *a = NULL, *p = NULL, *m = NULL, *d = NULL, *e = NULL; |
393 | BIGNUM *b = NULL, *n = NULL, *c = NULL; | |
394 | BN_MONT_CTX *mont = NULL; | |
30bea14b | 395 | int st = 0; |
0f113f3e | 396 | |
30bea14b RS |
397 | if (!TEST_ptr(a = BN_new()) |
398 | || !TEST_ptr(p = BN_new()) | |
399 | || !TEST_ptr(m = BN_new()) | |
400 | || !TEST_ptr(d = BN_new()) | |
401 | || !TEST_ptr(e = BN_new()) | |
402 | || !TEST_ptr(b = BN_new()) | |
403 | || !TEST_ptr(n = BN_new()) | |
404 | || !TEST_ptr(c = BN_new()) | |
405 | || !TEST_ptr(mont = BN_MONT_CTX_new())) | |
406 | goto err; | |
0f113f3e | 407 | |
e2f50811 SL |
408 | /* must be odd for montgomery */ |
409 | if (!(TEST_true(BN_bntest_rand(m, 1024, 0, 1)) | |
410 | /* Zero exponent */ | |
411 | && TEST_true(BN_bntest_rand(a, 1024, 0, 0)))) | |
412 | goto err; | |
8d1ebff4 | 413 | BN_zero(p); |
e2f50811 | 414 | |
30bea14b RS |
415 | if (!TEST_true(BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL))) |
416 | goto err; | |
dc352c19 | 417 | if (!TEST_BN_eq_one(d)) |
30bea14b | 418 | goto err; |
0f113f3e | 419 | |
8d1ebff4 | 420 | /* Regression test for carry bug in mulx4x_mont */ |
e2f50811 | 421 | if (!(TEST_true(BN_hex2bn(&a, |
8d1ebff4 RS |
422 | "7878787878787878787878787878787878787878787878787878787878787878" |
423 | "7878787878787878787878787878787878787878787878787878787878787878" | |
424 | "7878787878787878787878787878787878787878787878787878787878787878" | |
e2f50811 SL |
425 | "7878787878787878787878787878787878787878787878787878787878787878")) |
426 | && TEST_true(BN_hex2bn(&b, | |
8d1ebff4 RS |
427 | "095D72C08C097BA488C5E439C655A192EAFB6380073D8C2664668EDDB4060744" |
428 | "E16E57FB4EDB9AE10A0CEFCDC28A894F689A128379DB279D48A2E20849D68593" | |
429 | "9B7803BCF46CEBF5C533FB0DD35B080593DE5472E3FE5DB951B8BFF9B4CB8F03" | |
e2f50811 SL |
430 | "9CC638A5EE8CDD703719F8000E6A9F63BEED5F2FCD52FF293EA05A251BB4AB81")) |
431 | && TEST_true(BN_hex2bn(&n, | |
8d1ebff4 RS |
432 | "D78AF684E71DB0C39CFF4E64FB9DB567132CB9C50CC98009FEB820B26F2DED9B" |
433 | "91B9B5E2B83AE0AE4EB4E0523CA726BFBE969B89FD754F674CE99118C3F2D1C5" | |
434 | "D81FDC7C54E02B60262B241D53C040E99E45826ECA37A804668E690E1AFC1CA4" | |
e2f50811 SL |
435 | "2C9A15D84D4954425F0B7642FC0BD9D7B24E2618D2DCC9B729D944BADACFDDAF")))) |
436 | goto err; | |
437 | ||
438 | if (!(TEST_true(BN_MONT_CTX_set(mont, n, ctx)) | |
439 | && TEST_true(BN_mod_mul_montgomery(c, a, b, mont, ctx)) | |
440 | && TEST_true(BN_mod_mul_montgomery(d, b, a, mont, ctx)) | |
441 | && TEST_BN_eq(c, d))) | |
30bea14b | 442 | goto err; |
0f113f3e | 443 | |
3e7a4963 | 444 | /* Regression test for carry bug in sqr[x]8x_mont */ |
e2f50811 SL |
445 | if (!(TEST_true(parse_bigBN(&n, bn1strings)) |
446 | && TEST_true(parse_bigBN(&a, bn2strings)))) | |
447 | goto err; | |
26a39fa9 | 448 | BN_free(b); |
e2f50811 SL |
449 | if (!(TEST_ptr(b = BN_dup(a)) |
450 | && TEST_true(BN_MONT_CTX_set(mont, n, ctx)) | |
451 | && TEST_true(BN_mod_mul_montgomery(c, a, a, mont, ctx)) | |
452 | && TEST_true(BN_mod_mul_montgomery(d, a, b, mont, ctx)) | |
453 | && TEST_BN_eq(c, d))) | |
30bea14b | 454 | goto err; |
3e7a4963 | 455 | |
420b88ce AP |
456 | /* Regression test for carry bug in bn_sqrx8x_internal */ |
457 | { | |
458 | static const char *ahex[] = { | |
459 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
460 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
461 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
462 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
463 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8FFEADBCFC4DAE7FFF908E92820306B", | |
464 | "9544D954000000006C0000000000000000000000000000000000000000000000", | |
465 | "00000000000000000000FF030202FFFFF8FFEBDBCFC4DAE7FFF908E92820306B", | |
466 | "9544D954000000006C000000FF0302030000000000FFFFFFFFFFFFFFFFFFFFFF", | |
467 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01FC00FF02FFFFFFFF", | |
468 | "00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FCFD", | |
469 | "FCFFFFFFFFFF000000000000000000FF0302030000000000FFFFFFFFFFFFFFFF", | |
470 | "FF00FCFDFDFF030202FF00000000FFFFFFFFFFFFFFFFFF00FCFDFCFFFFFFFFFF", | |
471 | NULL | |
4483fbae | 472 | }; |
420b88ce AP |
473 | static const char *nhex[] = { |
474 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
475 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
476 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
477 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
478 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8F8000000", | |
479 | "00000010000000006C0000000000000000000000000000000000000000000000", | |
480 | "00000000000000000000000000000000000000FFFFFFFFFFFFF8F8F8F8000000", | |
481 | "00000010000000006C000000000000000000000000FFFFFFFFFFFFFFFFFFFFFF", | |
482 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
483 | "00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
484 | "FFFFFFFFFFFF000000000000000000000000000000000000FFFFFFFFFFFFFFFF", | |
485 | "FFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | |
486 | NULL | |
4483fbae F |
487 | }; |
488 | ||
e2f50811 SL |
489 | if (!(TEST_true(parse_bigBN(&a, ahex)) |
490 | && TEST_true(parse_bigBN(&n, nhex)))) | |
491 | goto err; | |
420b88ce AP |
492 | } |
493 | BN_free(b); | |
e2f50811 SL |
494 | if (!(TEST_ptr(b = BN_dup(a)) |
495 | && TEST_true(BN_MONT_CTX_set(mont, n, ctx)))) | |
496 | goto err; | |
497 | ||
f91e026e BE |
498 | if (!TEST_true(BN_mod_mul_montgomery(c, a, a, mont, ctx)) |
499 | || !TEST_true(BN_mod_mul_montgomery(d, a, b, mont, ctx)) | |
500 | || !TEST_BN_eq(c, d)) | |
501 | goto err; | |
502 | ||
503 | /* Regression test for bug in BN_from_montgomery_word */ | |
e2f50811 | 504 | if (!(TEST_true(BN_hex2bn(&a, |
f91e026e BE |
505 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" |
506 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | |
e2f50811 SL |
507 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) |
508 | && TEST_true(BN_hex2bn(&n, | |
f91e026e | 509 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" |
e2f50811 SL |
510 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) |
511 | && TEST_true(BN_MONT_CTX_set(mont, n, ctx)) | |
512 | && TEST_false(BN_mod_mul_montgomery(d, a, a, mont, ctx)))) | |
420b88ce AP |
513 | goto err; |
514 | ||
77d75993 | 515 | /* Regression test for bug in rsaz_1024_mul_avx2 */ |
e2f50811 | 516 | if (!(TEST_true(BN_hex2bn(&a, |
77d75993 AP |
517 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" |
518 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | |
519 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | |
e2f50811 SL |
520 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2020202020DF")) |
521 | && TEST_true(BN_hex2bn(&b, | |
77d75993 AP |
522 | "2020202020202020202020202020202020202020202020202020202020202020" |
523 | "2020202020202020202020202020202020202020202020202020202020202020" | |
524 | "20202020202020FF202020202020202020202020202020202020202020202020" | |
e2f50811 SL |
525 | "2020202020202020202020202020202020202020202020202020202020202020")) |
526 | && TEST_true(BN_hex2bn(&n, | |
77d75993 AP |
527 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" |
528 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | |
529 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | |
e2f50811 SL |
530 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2020202020FF")) |
531 | && TEST_true(BN_MONT_CTX_set(mont, n, ctx)) | |
532 | && TEST_true(BN_mod_exp_mont_consttime(c, a, b, n, ctx, mont)) | |
533 | && TEST_true(BN_mod_exp_mont(d, a, b, n, ctx, mont)) | |
534 | && TEST_BN_eq(c, d))) | |
77d75993 AP |
535 | goto err; |
536 | ||
3afd537a DB |
537 | /* |
538 | * rsaz_1024_mul_avx2 expects fully-reduced inputs. | |
539 | * BN_mod_exp_mont_consttime should reduce the input first. | |
540 | */ | |
e2f50811 | 541 | if (!(TEST_true(BN_hex2bn(&a, |
3afd537a DB |
542 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" |
543 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | |
544 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | |
e2f50811 SL |
545 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2020202020DF")) |
546 | && TEST_true(BN_hex2bn(&b, | |
3afd537a DB |
547 | "1FA53F26F8811C58BE0357897AA5E165693230BC9DF5F01DFA6A2D59229EC69D" |
548 | "9DE6A89C36E3B6957B22D6FAAD5A3C73AE587B710DBE92E83D3A9A3339A085CB" | |
549 | "B58F508CA4F837924BB52CC1698B7FDC2FD74362456A595A5B58E38E38E38E38" | |
e2f50811 SL |
550 | "E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E")) |
551 | && TEST_true(BN_hex2bn(&n, | |
3afd537a DB |
552 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" |
553 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | |
554 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | |
e2f50811 SL |
555 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2020202020DF")) |
556 | && TEST_true(BN_MONT_CTX_set(mont, n, ctx)) | |
557 | && TEST_true(BN_mod_exp_mont_consttime(c, a, b, n, ctx, mont)))) | |
558 | goto err; | |
3afd537a DB |
559 | BN_zero(d); |
560 | if (!TEST_BN_eq(c, d)) | |
561 | goto err; | |
562 | ||
8d1ebff4 | 563 | /* Zero input */ |
e2f50811 SL |
564 | if (!TEST_true(BN_bntest_rand(p, 1024, 0, 0))) |
565 | goto err; | |
8d1ebff4 | 566 | BN_zero(a); |
30bea14b | 567 | if (!TEST_true(BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) |
dc352c19 | 568 | || !TEST_BN_eq_zero(d)) |
30bea14b RS |
569 | goto err; |
570 | ||
8d1ebff4 RS |
571 | /* |
572 | * Craft an input whose Montgomery representation is 1, i.e., shorter | |
573 | * than the modulus m, in order to test the const time precomputation | |
574 | * scattering/gathering. | |
575 | */ | |
e2f50811 SL |
576 | if (!(TEST_true(BN_one(a)) |
577 | && TEST_true(BN_MONT_CTX_set(mont, m, ctx)))) | |
578 | goto err; | |
30bea14b RS |
579 | if (!TEST_true(BN_from_montgomery(e, a, mont, ctx)) |
580 | || !TEST_true(BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) | |
581 | || !TEST_true(BN_mod_exp_simple(a, e, p, m, ctx)) | |
dc352c19 | 582 | || !TEST_BN_eq(a, d)) |
30bea14b RS |
583 | goto err; |
584 | ||
8d1ebff4 | 585 | /* Finally, some regular test vectors. */ |
e2f50811 SL |
586 | if (!(TEST_true(BN_bntest_rand(e, 1024, 0, 0)) |
587 | && TEST_true(BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) | |
588 | && TEST_true(BN_mod_exp_simple(a, e, p, m, ctx)) | |
589 | && TEST_BN_eq(a, d))) | |
30bea14b RS |
590 | goto err; |
591 | ||
592 | st = 1; | |
593 | ||
fe16ae5f | 594 | err: |
0f113f3e MC |
595 | BN_MONT_CTX_free(mont); |
596 | BN_free(a); | |
8d1ebff4 RS |
597 | BN_free(p); |
598 | BN_free(m); | |
0f113f3e | 599 | BN_free(d); |
8d1ebff4 RS |
600 | BN_free(e); |
601 | BN_free(b); | |
0f113f3e | 602 | BN_free(n); |
8d1ebff4 | 603 | BN_free(c); |
30bea14b | 604 | return st; |
0f113f3e | 605 | } |
d02b48c6 | 606 | |
8d1ebff4 | 607 | #ifndef OPENSSL_NO_EC2M |
31a80694 | 608 | static int test_gf2m_add(void) |
0f113f3e | 609 | { |
30bea14b | 610 | BIGNUM *a = NULL, *b = NULL, *c = NULL; |
8d1ebff4 | 611 | int i, st = 0; |
0f113f3e | 612 | |
30bea14b RS |
613 | if (!TEST_ptr(a = BN_new()) |
614 | || !TEST_ptr(b = BN_new()) | |
615 | || !TEST_ptr(c = BN_new())) | |
616 | goto err; | |
0f113f3e | 617 | |
8d1ebff4 | 618 | for (i = 0; i < NUM0; i++) { |
e2f50811 SL |
619 | if (!(TEST_true(BN_rand(a, 512, 0, 0)) |
620 | && TEST_ptr(BN_copy(b, BN_value_one())))) | |
621 | goto err; | |
2b1aa198 RL |
622 | BN_set_negative(a, rand_neg()); |
623 | BN_set_negative(b, rand_neg()); | |
e2f50811 SL |
624 | if (!(TEST_true(BN_GF2m_add(c, a, b)) |
625 | /* Test that two added values have the correct parity. */ | |
626 | && TEST_false((BN_is_odd(a) && BN_is_odd(c)) | |
627 | || (!BN_is_odd(a) && !BN_is_odd(c))))) | |
8d1ebff4 | 628 | goto err; |
e2f50811 SL |
629 | if (!(TEST_true(BN_GF2m_add(c, c, c)) |
630 | /* Test that c + c = 0. */ | |
631 | && TEST_BN_eq_zero(c))) | |
8d1ebff4 | 632 | goto err; |
0f113f3e | 633 | } |
8d1ebff4 RS |
634 | st = 1; |
635 | err: | |
0f113f3e MC |
636 | BN_free(a); |
637 | BN_free(b); | |
638 | BN_free(c); | |
8d1ebff4 | 639 | return st; |
0f113f3e | 640 | } |
d02b48c6 | 641 | |
31a80694 | 642 | static int test_gf2m_mod(void) |
0f113f3e | 643 | { |
30bea14b | 644 | BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL, *e = NULL; |
8d1ebff4 | 645 | int i, j, st = 0; |
0f113f3e | 646 | |
30bea14b RS |
647 | if (!TEST_ptr(a = BN_new()) |
648 | || !TEST_ptr(b[0] = BN_new()) | |
649 | || !TEST_ptr(b[1] = BN_new()) | |
650 | || !TEST_ptr(c = BN_new()) | |
651 | || !TEST_ptr(d = BN_new()) | |
652 | || !TEST_ptr(e = BN_new())) | |
653 | goto err; | |
0f113f3e | 654 | |
e2f50811 SL |
655 | if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0])) |
656 | && TEST_true(BN_GF2m_arr2poly(p1, b[1])))) | |
657 | goto err; | |
0f113f3e | 658 | |
8d1ebff4 | 659 | for (i = 0; i < NUM0; i++) { |
e2f50811 SL |
660 | if (!TEST_true(BN_bntest_rand(a, 1024, 0, 0))) |
661 | goto err; | |
8d1ebff4 | 662 | for (j = 0; j < 2; j++) { |
e2f50811 SL |
663 | if (!(TEST_true(BN_GF2m_mod(c, a, b[j])) |
664 | && TEST_true(BN_GF2m_add(d, a, c)) | |
665 | && TEST_true(BN_GF2m_mod(e, d, b[j])) | |
666 | /* Test that a + (a mod p) mod p == 0. */ | |
667 | && TEST_BN_eq_zero(e))) | |
8d1ebff4 | 668 | goto err; |
0f113f3e MC |
669 | } |
670 | } | |
8d1ebff4 RS |
671 | st = 1; |
672 | err: | |
0f113f3e | 673 | BN_free(a); |
8d1ebff4 RS |
674 | BN_free(b[0]); |
675 | BN_free(b[1]); | |
0f113f3e MC |
676 | BN_free(c); |
677 | BN_free(d); | |
678 | BN_free(e); | |
8d1ebff4 | 679 | return st; |
0f113f3e | 680 | } |
d02b48c6 | 681 | |
31a80694 | 682 | static int test_gf2m_mul(void) |
0f113f3e | 683 | { |
30bea14b RS |
684 | BIGNUM *a, *b[2] = {NULL, NULL}, *c = NULL, *d = NULL; |
685 | BIGNUM *e = NULL, *f = NULL, *g = NULL, *h = NULL; | |
8d1ebff4 | 686 | int i, j, st = 0; |
30bea14b RS |
687 | |
688 | if (!TEST_ptr(a = BN_new()) | |
689 | || !TEST_ptr(b[0] = BN_new()) | |
690 | || !TEST_ptr(b[1] = BN_new()) | |
691 | || !TEST_ptr(c = BN_new()) | |
692 | || !TEST_ptr(d = BN_new()) | |
693 | || !TEST_ptr(e = BN_new()) | |
694 | || !TEST_ptr(f = BN_new()) | |
695 | || !TEST_ptr(g = BN_new()) | |
696 | || !TEST_ptr(h = BN_new())) | |
697 | goto err; | |
0f113f3e | 698 | |
e2f50811 SL |
699 | if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0])) |
700 | && TEST_true(BN_GF2m_arr2poly(p1, b[1])))) | |
701 | goto err; | |
0f113f3e | 702 | |
8d1ebff4 | 703 | for (i = 0; i < NUM0; i++) { |
e2f50811 SL |
704 | if (!(TEST_true(BN_bntest_rand(a, 1024, 0, 0)) |
705 | && TEST_true(BN_bntest_rand(c, 1024, 0, 0)) | |
706 | && TEST_true(BN_bntest_rand(d, 1024, 0, 0)))) | |
707 | goto err; | |
8d1ebff4 | 708 | for (j = 0; j < 2; j++) { |
e2f50811 SL |
709 | if (!(TEST_true(BN_GF2m_mod_mul(e, a, c, b[j], ctx)) |
710 | && TEST_true(BN_GF2m_add(f, a, d)) | |
711 | && TEST_true(BN_GF2m_mod_mul(g, f, c, b[j], ctx)) | |
712 | && TEST_true(BN_GF2m_mod_mul(h, d, c, b[j], ctx)) | |
713 | && TEST_true(BN_GF2m_add(f, e, g)) | |
714 | && TEST_true(BN_GF2m_add(f, f, h)) | |
715 | /* Test that (a+d)*c = a*c + d*c. */ | |
716 | && TEST_BN_eq_zero(f))) | |
8d1ebff4 | 717 | goto err; |
0f113f3e | 718 | } |
29851264 | 719 | } |
8d1ebff4 | 720 | st = 1; |
30bea14b | 721 | |
8d1ebff4 | 722 | err: |
0f113f3e | 723 | BN_free(a); |
8d1ebff4 RS |
724 | BN_free(b[0]); |
725 | BN_free(b[1]); | |
0f113f3e MC |
726 | BN_free(c); |
727 | BN_free(d); | |
728 | BN_free(e); | |
8d1ebff4 RS |
729 | BN_free(f); |
730 | BN_free(g); | |
731 | BN_free(h); | |
732 | return st; | |
0f113f3e | 733 | } |
d02b48c6 | 734 | |
31a80694 | 735 | static int test_gf2m_sqr(void) |
0f113f3e | 736 | { |
30bea14b | 737 | BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL; |
8d1ebff4 | 738 | int i, j, st = 0; |
0f113f3e | 739 | |
30bea14b RS |
740 | if (!TEST_ptr(a = BN_new()) |
741 | || !TEST_ptr(b[0] = BN_new()) | |
742 | || !TEST_ptr(b[1] = BN_new()) | |
743 | || !TEST_ptr(c = BN_new()) | |
744 | || !TEST_ptr(d = BN_new())) | |
745 | goto err; | |
a9009e51 | 746 | |
e2f50811 SL |
747 | if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0])) |
748 | && TEST_true(BN_GF2m_arr2poly(p1, b[1])))) | |
749 | goto err; | |
0f113f3e | 750 | |
8d1ebff4 | 751 | for (i = 0; i < NUM0; i++) { |
e2f50811 SL |
752 | if (!TEST_true(BN_bntest_rand(a, 1024, 0, 0))) |
753 | goto err; | |
8d1ebff4 | 754 | for (j = 0; j < 2; j++) { |
e2f50811 SL |
755 | if (!(TEST_true(BN_GF2m_mod_sqr(c, a, b[j], ctx)) |
756 | && TEST_true(BN_copy(d, a)) | |
757 | && TEST_true(BN_GF2m_mod_mul(d, a, d, b[j], ctx)) | |
758 | && TEST_true(BN_GF2m_add(d, c, d)) | |
759 | /* Test that a*a = a^2. */ | |
760 | && TEST_BN_eq_zero(d))) | |
8d1ebff4 | 761 | goto err; |
0f113f3e MC |
762 | } |
763 | } | |
8d1ebff4 RS |
764 | st = 1; |
765 | err: | |
0f113f3e | 766 | BN_free(a); |
8d1ebff4 RS |
767 | BN_free(b[0]); |
768 | BN_free(b[1]); | |
0f113f3e MC |
769 | BN_free(c); |
770 | BN_free(d); | |
8d1ebff4 | 771 | return st; |
0f113f3e MC |
772 | } |
773 | ||
31a80694 | 774 | static int test_gf2m_modinv(void) |
0f113f3e | 775 | { |
30bea14b | 776 | BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL; |
8d1ebff4 | 777 | int i, j, st = 0; |
0f113f3e | 778 | |
30bea14b RS |
779 | if (!TEST_ptr(a = BN_new()) |
780 | || !TEST_ptr(b[0] = BN_new()) | |
781 | || !TEST_ptr(b[1] = BN_new()) | |
782 | || !TEST_ptr(c = BN_new()) | |
783 | || !TEST_ptr(d = BN_new())) | |
784 | goto err; | |
0f113f3e | 785 | |
e2f50811 SL |
786 | if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0])) |
787 | && TEST_true(BN_GF2m_arr2poly(p1, b[1])))) | |
788 | goto err; | |
0f113f3e | 789 | |
8d1ebff4 | 790 | for (i = 0; i < NUM0; i++) { |
e2f50811 SL |
791 | if (!TEST_true(BN_bntest_rand(a, 512, 0, 0))) |
792 | goto err; | |
0f113f3e | 793 | for (j = 0; j < 2; j++) { |
e2f50811 SL |
794 | if (!(TEST_true(BN_GF2m_mod_inv(c, a, b[j], ctx)) |
795 | && TEST_true(BN_GF2m_mod_mul(d, a, c, b[j], ctx)) | |
796 | /* Test that ((1/a)*a) = 1. */ | |
797 | && TEST_BN_eq_one(d))) | |
0f113f3e | 798 | goto err; |
0f113f3e MC |
799 | } |
800 | } | |
8d1ebff4 | 801 | st = 1; |
0f113f3e MC |
802 | err: |
803 | BN_free(a); | |
804 | BN_free(b[0]); | |
805 | BN_free(b[1]); | |
806 | BN_free(c); | |
807 | BN_free(d); | |
8d1ebff4 | 808 | return st; |
0f113f3e MC |
809 | } |
810 | ||
31a80694 | 811 | static int test_gf2m_moddiv(void) |
0f113f3e | 812 | { |
30bea14b RS |
813 | BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL; |
814 | BIGNUM *e = NULL, *f = NULL; | |
8d1ebff4 | 815 | int i, j, st = 0; |
0f113f3e | 816 | |
30bea14b RS |
817 | if (!TEST_ptr(a = BN_new()) |
818 | || !TEST_ptr(b[0] = BN_new()) | |
819 | || !TEST_ptr(b[1] = BN_new()) | |
820 | || !TEST_ptr(c = BN_new()) | |
821 | || !TEST_ptr(d = BN_new()) | |
822 | || !TEST_ptr(e = BN_new()) | |
823 | || !TEST_ptr(f = BN_new())) | |
824 | goto err; | |
0f113f3e | 825 | |
e2f50811 SL |
826 | if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0])) |
827 | && TEST_true(BN_GF2m_arr2poly(p1, b[1])))) | |
828 | goto err; | |
0f113f3e | 829 | |
8d1ebff4 | 830 | for (i = 0; i < NUM0; i++) { |
e2f50811 SL |
831 | if (!(TEST_true(BN_bntest_rand(a, 512, 0, 0)) |
832 | && TEST_true(BN_bntest_rand(c, 512, 0, 0)))) | |
833 | goto err; | |
0f113f3e | 834 | for (j = 0; j < 2; j++) { |
e2f50811 SL |
835 | if (!(TEST_true(BN_GF2m_mod_div(d, a, c, b[j], ctx)) |
836 | && TEST_true(BN_GF2m_mod_mul(e, d, c, b[j], ctx)) | |
837 | && TEST_true(BN_GF2m_mod_div(f, a, e, b[j], ctx)) | |
838 | /* Test that ((a/c)*c)/a = 1. */ | |
839 | && TEST_BN_eq_one(f))) | |
0f113f3e | 840 | goto err; |
0f113f3e MC |
841 | } |
842 | } | |
8d1ebff4 | 843 | st = 1; |
0f113f3e MC |
844 | err: |
845 | BN_free(a); | |
846 | BN_free(b[0]); | |
847 | BN_free(b[1]); | |
848 | BN_free(c); | |
849 | BN_free(d); | |
850 | BN_free(e); | |
851 | BN_free(f); | |
8d1ebff4 | 852 | return st; |
0f113f3e MC |
853 | } |
854 | ||
31a80694 | 855 | static int test_gf2m_modexp(void) |
0f113f3e | 856 | { |
30bea14b RS |
857 | BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL; |
858 | BIGNUM *e = NULL, *f = NULL; | |
8d1ebff4 | 859 | int i, j, st = 0; |
0f113f3e | 860 | |
30bea14b RS |
861 | if (!TEST_ptr(a = BN_new()) |
862 | || !TEST_ptr(b[0] = BN_new()) | |
863 | || !TEST_ptr(b[1] = BN_new()) | |
864 | || !TEST_ptr(c = BN_new()) | |
865 | || !TEST_ptr(d = BN_new()) | |
866 | || !TEST_ptr(e = BN_new()) | |
867 | || !TEST_ptr(f = BN_new())) | |
868 | goto err; | |
0f113f3e | 869 | |
e2f50811 SL |
870 | if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0])) |
871 | && TEST_true(BN_GF2m_arr2poly(p1, b[1])))) | |
872 | goto err; | |
0f113f3e | 873 | |
8d1ebff4 | 874 | for (i = 0; i < NUM0; i++) { |
e2f50811 SL |
875 | if (!(TEST_true(BN_bntest_rand(a, 512, 0, 0)) |
876 | && TEST_true(BN_bntest_rand(c, 512, 0, 0)) | |
877 | && TEST_true(BN_bntest_rand(d, 512, 0, 0)))) | |
878 | goto err; | |
0f113f3e | 879 | for (j = 0; j < 2; j++) { |
e2f50811 SL |
880 | if (!(TEST_true(BN_GF2m_mod_exp(e, a, c, b[j], ctx)) |
881 | && TEST_true(BN_GF2m_mod_exp(f, a, d, b[j], ctx)) | |
882 | && TEST_true(BN_GF2m_mod_mul(e, e, f, b[j], ctx)) | |
883 | && TEST_true(BN_add(f, c, d)) | |
884 | && TEST_true(BN_GF2m_mod_exp(f, a, f, b[j], ctx)) | |
885 | && TEST_true(BN_GF2m_add(f, e, f)) | |
886 | /* Test that a^(c+d)=a^c*a^d. */ | |
887 | && TEST_BN_eq_zero(f))) | |
0f113f3e | 888 | goto err; |
0f113f3e MC |
889 | } |
890 | } | |
8d1ebff4 | 891 | st = 1; |
0f113f3e MC |
892 | err: |
893 | BN_free(a); | |
894 | BN_free(b[0]); | |
895 | BN_free(b[1]); | |
896 | BN_free(c); | |
897 | BN_free(d); | |
898 | BN_free(e); | |
899 | BN_free(f); | |
8d1ebff4 | 900 | return st; |
0f113f3e MC |
901 | } |
902 | ||
31a80694 | 903 | static int test_gf2m_modsqrt(void) |
0f113f3e | 904 | { |
30bea14b RS |
905 | BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL; |
906 | BIGNUM *e = NULL, *f = NULL; | |
8d1ebff4 | 907 | int i, j, st = 0; |
0f113f3e | 908 | |
30bea14b RS |
909 | if (!TEST_ptr(a = BN_new()) |
910 | || !TEST_ptr(b[0] = BN_new()) | |
911 | || !TEST_ptr(b[1] = BN_new()) | |
912 | || !TEST_ptr(c = BN_new()) | |
913 | || !TEST_ptr(d = BN_new()) | |
914 | || !TEST_ptr(e = BN_new()) | |
915 | || !TEST_ptr(f = BN_new())) | |
916 | goto err; | |
0f113f3e | 917 | |
e2f50811 SL |
918 | if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0])) |
919 | && TEST_true(BN_GF2m_arr2poly(p1, b[1])))) | |
920 | goto err; | |
0f113f3e | 921 | |
8d1ebff4 | 922 | for (i = 0; i < NUM0; i++) { |
e2f50811 SL |
923 | if (!TEST_true(BN_bntest_rand(a, 512, 0, 0))) |
924 | goto err; | |
925 | ||
0f113f3e | 926 | for (j = 0; j < 2; j++) { |
e2f50811 SL |
927 | if (!(TEST_true(BN_GF2m_mod(c, a, b[j])) |
928 | && TEST_true(BN_GF2m_mod_sqrt(d, a, b[j], ctx)) | |
929 | && TEST_true(BN_GF2m_mod_sqr(e, d, b[j], ctx)) | |
930 | && TEST_true(BN_GF2m_add(f, c, e)) | |
931 | /* Test that d^2 = a, where d = sqrt(a). */ | |
932 | && TEST_BN_eq_zero(f))) | |
0f113f3e | 933 | goto err; |
0f113f3e MC |
934 | } |
935 | } | |
8d1ebff4 | 936 | st = 1; |
0f113f3e MC |
937 | err: |
938 | BN_free(a); | |
939 | BN_free(b[0]); | |
940 | BN_free(b[1]); | |
941 | BN_free(c); | |
942 | BN_free(d); | |
943 | BN_free(e); | |
944 | BN_free(f); | |
8d1ebff4 | 945 | return st; |
0f113f3e MC |
946 | } |
947 | ||
31a80694 | 948 | static int test_gf2m_modsolvequad(void) |
0f113f3e | 949 | { |
30bea14b RS |
950 | BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL; |
951 | BIGNUM *e = NULL; | |
8d1ebff4 | 952 | int i, j, s = 0, t, st = 0; |
0f113f3e | 953 | |
30bea14b RS |
954 | if (!TEST_ptr(a = BN_new()) |
955 | || !TEST_ptr(b[0] = BN_new()) | |
956 | || !TEST_ptr(b[1] = BN_new()) | |
957 | || !TEST_ptr(c = BN_new()) | |
958 | || !TEST_ptr(d = BN_new()) | |
959 | || !TEST_ptr(e = BN_new())) | |
960 | goto err; | |
0f113f3e | 961 | |
e2f50811 SL |
962 | if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0])) |
963 | && TEST_true(BN_GF2m_arr2poly(p1, b[1])))) | |
964 | goto err; | |
0f113f3e | 965 | |
8d1ebff4 | 966 | for (i = 0; i < NUM0; i++) { |
e2f50811 SL |
967 | if (!TEST_true(BN_bntest_rand(a, 512, 0, 0))) |
968 | goto err; | |
0f113f3e MC |
969 | for (j = 0; j < 2; j++) { |
970 | t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx); | |
971 | if (t) { | |
972 | s++; | |
e2f50811 SL |
973 | if (!(TEST_true(BN_GF2m_mod_sqr(d, c, b[j], ctx)) |
974 | && TEST_true(BN_GF2m_add(d, c, d)) | |
975 | && TEST_true(BN_GF2m_mod(e, a, b[j])) | |
976 | && TEST_true(BN_GF2m_add(e, e, d)) | |
977 | /* | |
978 | * Test that solution of quadratic c | |
979 | * satisfies c^2 + c = a. | |
980 | */ | |
981 | && TEST_BN_eq_zero(e))) | |
0f113f3e | 982 | goto err; |
0f113f3e MC |
983 | } |
984 | } | |
985 | } | |
30bea14b RS |
986 | if (!TEST_int_ge(s, 0)) { |
987 | TEST_info("%d tests found no roots; probably an error", NUM0); | |
0f113f3e MC |
988 | goto err; |
989 | } | |
8d1ebff4 | 990 | st = 1; |
0f113f3e MC |
991 | err: |
992 | BN_free(a); | |
993 | BN_free(b[0]); | |
994 | BN_free(b[1]); | |
995 | BN_free(c); | |
996 | BN_free(d); | |
997 | BN_free(e); | |
8d1ebff4 | 998 | return st; |
0f113f3e | 999 | } |
b3310161 | 1000 | #endif |
8d1ebff4 | 1001 | |
31a80694 | 1002 | static int test_kronecker(void) |
0f113f3e | 1003 | { |
30bea14b RS |
1004 | BIGNUM *a = NULL, *b = NULL, *r = NULL, *t = NULL; |
1005 | int i, legendre, kronecker, st = 0; | |
8d1ebff4 | 1006 | |
30bea14b RS |
1007 | if (!TEST_ptr(a = BN_new()) |
1008 | || !TEST_ptr(b = BN_new()) | |
1009 | || !TEST_ptr(r = BN_new()) | |
1010 | || !TEST_ptr(t = BN_new())) | |
8d1ebff4 RS |
1011 | goto err; |
1012 | ||
1013 | /* | |
1014 | * We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol). In | |
1015 | * this case we know that if b is prime, then BN_kronecker(a, b, ctx) is | |
1016 | * congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol). So we | |
1017 | * generate a random prime b and compare these values for a number of | |
1018 | * random a's. (That is, we run the Solovay-Strassen primality test to | |
1019 | * confirm that b is prime, except that we don't want to test whether b | |
1020 | * is prime but whether BN_kronecker works.) | |
1021 | */ | |
1022 | ||
30bea14b | 1023 | if (!TEST_true(BN_generate_prime_ex(b, 512, 0, NULL, NULL, NULL))) |
8d1ebff4 | 1024 | goto err; |
2b1aa198 | 1025 | BN_set_negative(b, rand_neg()); |
8d1ebff4 RS |
1026 | |
1027 | for (i = 0; i < NUM0; i++) { | |
30bea14b | 1028 | if (!TEST_true(BN_bntest_rand(a, 512, 0, 0))) |
8d1ebff4 | 1029 | goto err; |
2b1aa198 | 1030 | BN_set_negative(a, rand_neg()); |
8d1ebff4 RS |
1031 | |
1032 | /* t := (|b|-1)/2 (note that b is odd) */ | |
30bea14b | 1033 | if (!TEST_true(BN_copy(t, b))) |
8d1ebff4 | 1034 | goto err; |
2b1aa198 | 1035 | BN_set_negative(t, 0); |
30bea14b | 1036 | if (!TEST_true(BN_sub_word(t, 1))) |
8d1ebff4 | 1037 | goto err; |
30bea14b | 1038 | if (!TEST_true(BN_rshift1(t, t))) |
8d1ebff4 RS |
1039 | goto err; |
1040 | /* r := a^t mod b */ | |
2b1aa198 | 1041 | BN_set_negative(b, 0); |
8d1ebff4 | 1042 | |
30bea14b | 1043 | if (!TEST_true(BN_mod_exp_recp(r, a, t, b, ctx))) |
8d1ebff4 | 1044 | goto err; |
2b1aa198 | 1045 | BN_set_negative(b, 1); |
8d1ebff4 RS |
1046 | |
1047 | if (BN_is_word(r, 1)) | |
1048 | legendre = 1; | |
1049 | else if (BN_is_zero(r)) | |
1050 | legendre = 0; | |
1051 | else { | |
30bea14b | 1052 | if (!TEST_true(BN_add_word(r, 1))) |
8d1ebff4 | 1053 | goto err; |
30bea14b RS |
1054 | if (!TEST_int_eq(BN_ucmp(r, b), 0)) { |
1055 | TEST_info("Legendre symbol computation failed"); | |
8d1ebff4 RS |
1056 | goto err; |
1057 | } | |
1058 | legendre = -1; | |
1059 | } | |
1060 | ||
30bea14b | 1061 | if (!TEST_int_ge(kronecker = BN_kronecker(a, b, ctx), -1)) |
8d1ebff4 RS |
1062 | goto err; |
1063 | /* we actually need BN_kronecker(a, |b|) */ | |
2b1aa198 | 1064 | if (BN_is_negative(a) && BN_is_negative(b)) |
8d1ebff4 RS |
1065 | kronecker = -kronecker; |
1066 | ||
30bea14b | 1067 | if (!TEST_int_eq(legendre, kronecker)) |
8d1ebff4 | 1068 | goto err; |
8d1ebff4 RS |
1069 | } |
1070 | ||
1071 | st = 1; | |
1072 | err: | |
1073 | BN_free(a); | |
1074 | BN_free(b); | |
1075 | BN_free(r); | |
1076 | BN_free(t); | |
1077 | return st; | |
1078 | } | |
1079 | ||
1080 | static int file_sum(STANZA *s) | |
1081 | { | |
30bea14b | 1082 | BIGNUM *a = NULL, *b = NULL, *sum = NULL, *ret = NULL; |
8d1ebff4 RS |
1083 | BN_ULONG b_word; |
1084 | int st = 0; | |
1085 | ||
30bea14b RS |
1086 | if (!TEST_ptr(a = getBN(s, "A")) |
1087 | || !TEST_ptr(b = getBN(s, "B")) | |
1088 | || !TEST_ptr(sum = getBN(s, "Sum")) | |
1089 | || !TEST_ptr(ret = BN_new())) | |
8d1ebff4 RS |
1090 | goto err; |
1091 | ||
30bea14b | 1092 | if (!TEST_true(BN_add(ret, a, b)) |
8d1ebff4 | 1093 | || !equalBN("A + B", sum, ret) |
30bea14b | 1094 | || !TEST_true(BN_sub(ret, sum, a)) |
8d1ebff4 | 1095 | || !equalBN("Sum - A", b, ret) |
30bea14b | 1096 | || !TEST_true(BN_sub(ret, sum, b)) |
8d1ebff4 RS |
1097 | || !equalBN("Sum - B", a, ret)) |
1098 | goto err; | |
1099 | ||
1100 | /* | |
1101 | * Test that the functions work when |r| and |a| point to the same BIGNUM, | |
1102 | * or when |r| and |b| point to the same BIGNUM. | |
1103 | * TODO: Test where all of |r|, |a|, and |b| point to the same BIGNUM. | |
1104 | */ | |
30bea14b RS |
1105 | if (!TEST_true(BN_copy(ret, a)) |
1106 | || !TEST_true(BN_add(ret, ret, b)) | |
8d1ebff4 | 1107 | || !equalBN("A + B (r is a)", sum, ret) |
30bea14b RS |
1108 | || !TEST_true(BN_copy(ret, b)) |
1109 | || !TEST_true(BN_add(ret, a, ret)) | |
8d1ebff4 | 1110 | || !equalBN("A + B (r is b)", sum, ret) |
30bea14b RS |
1111 | || !TEST_true(BN_copy(ret, sum)) |
1112 | || !TEST_true(BN_sub(ret, ret, a)) | |
8d1ebff4 | 1113 | || !equalBN("Sum - A (r is a)", b, ret) |
30bea14b RS |
1114 | || !TEST_true(BN_copy(ret, a)) |
1115 | || !TEST_true(BN_sub(ret, sum, ret)) | |
8d1ebff4 | 1116 | || !equalBN("Sum - A (r is b)", b, ret) |
30bea14b RS |
1117 | || !TEST_true(BN_copy(ret, sum)) |
1118 | || !TEST_true(BN_sub(ret, ret, b)) | |
8d1ebff4 | 1119 | || !equalBN("Sum - B (r is a)", a, ret) |
30bea14b RS |
1120 | || !TEST_true(BN_copy(ret, b)) |
1121 | || !TEST_true(BN_sub(ret, sum, ret)) | |
8d1ebff4 RS |
1122 | || !equalBN("Sum - B (r is b)", a, ret)) |
1123 | goto err; | |
1124 | ||
1125 | /* | |
1126 | * Test BN_uadd() and BN_usub() with the prerequisites they are | |
1127 | * documented as having. Note that these functions are frequently used | |
1128 | * when the prerequisites don't hold. In those cases, they are supposed | |
1129 | * to work as if the prerequisite hold, but we don't test that yet. | |
1130 | * TODO: test that. | |
1131 | */ | |
1132 | if (!BN_is_negative(a) && !BN_is_negative(b) && BN_cmp(a, b) >= 0) { | |
30bea14b | 1133 | if (!TEST_true(BN_uadd(ret, a, b)) |
8d1ebff4 | 1134 | || !equalBN("A +u B", sum, ret) |
30bea14b | 1135 | || !TEST_true(BN_usub(ret, sum, a)) |
8d1ebff4 | 1136 | || !equalBN("Sum -u A", b, ret) |
30bea14b | 1137 | || !TEST_true(BN_usub(ret, sum, b)) |
8d1ebff4 RS |
1138 | || !equalBN("Sum -u B", a, ret)) |
1139 | goto err; | |
1140 | /* | |
1141 | * Test that the functions work when |r| and |a| point to the same | |
1142 | * BIGNUM, or when |r| and |b| point to the same BIGNUM. | |
1143 | * TODO: Test where all of |r|, |a|, and |b| point to the same BIGNUM. | |
1144 | */ | |
30bea14b RS |
1145 | if (!TEST_true(BN_copy(ret, a)) |
1146 | || !TEST_true(BN_uadd(ret, ret, b)) | |
8d1ebff4 | 1147 | || !equalBN("A +u B (r is a)", sum, ret) |
30bea14b RS |
1148 | || !TEST_true(BN_copy(ret, b)) |
1149 | || !TEST_true(BN_uadd(ret, a, ret)) | |
8d1ebff4 | 1150 | || !equalBN("A +u B (r is b)", sum, ret) |
30bea14b RS |
1151 | || !TEST_true(BN_copy(ret, sum)) |
1152 | || !TEST_true(BN_usub(ret, ret, a)) | |
8d1ebff4 | 1153 | || !equalBN("Sum -u A (r is a)", b, ret) |
30bea14b RS |
1154 | || !TEST_true(BN_copy(ret, a)) |
1155 | || !TEST_true(BN_usub(ret, sum, ret)) | |
8d1ebff4 | 1156 | || !equalBN("Sum -u A (r is b)", b, ret) |
30bea14b RS |
1157 | || !TEST_true(BN_copy(ret, sum)) |
1158 | || !TEST_true(BN_usub(ret, ret, b)) | |
8d1ebff4 | 1159 | || !equalBN("Sum -u B (r is a)", a, ret) |
30bea14b RS |
1160 | || !TEST_true(BN_copy(ret, b)) |
1161 | || !TEST_true(BN_usub(ret, sum, ret)) | |
8d1ebff4 RS |
1162 | || !equalBN("Sum -u B (r is b)", a, ret)) |
1163 | goto err; | |
1164 | } | |
1165 | ||
1166 | /* | |
1167 | * Test with BN_add_word() and BN_sub_word() if |b| is small enough. | |
1168 | */ | |
1169 | b_word = BN_get_word(b); | |
1170 | if (!BN_is_negative(b) && b_word != (BN_ULONG)-1) { | |
30bea14b RS |
1171 | if (!TEST_true(BN_copy(ret, a)) |
1172 | || !TEST_true(BN_add_word(ret, b_word)) | |
8d1ebff4 | 1173 | || !equalBN("A + B (word)", sum, ret) |
30bea14b RS |
1174 | || !TEST_true(BN_copy(ret, sum)) |
1175 | || !TEST_true(BN_sub_word(ret, b_word)) | |
8d1ebff4 RS |
1176 | || !equalBN("Sum - B (word)", a, ret)) |
1177 | goto err; | |
1178 | } | |
1179 | st = 1; | |
1180 | ||
fe16ae5f | 1181 | err: |
8d1ebff4 RS |
1182 | BN_free(a); |
1183 | BN_free(b); | |
1184 | BN_free(sum); | |
1185 | BN_free(ret); | |
1186 | return st; | |
1187 | } | |
1188 | ||
1189 | static int file_lshift1(STANZA *s) | |
1190 | { | |
30bea14b RS |
1191 | BIGNUM *a = NULL, *lshift1 = NULL, *zero = NULL, *ret = NULL; |
1192 | BIGNUM *two = NULL, *remainder = NULL; | |
8d1ebff4 RS |
1193 | int st = 0; |
1194 | ||
30bea14b RS |
1195 | if (!TEST_ptr(a = getBN(s, "A")) |
1196 | || !TEST_ptr(lshift1 = getBN(s, "LShift1")) | |
1197 | || !TEST_ptr(zero = BN_new()) | |
1198 | || !TEST_ptr(ret = BN_new()) | |
1199 | || !TEST_ptr(two = BN_new()) | |
1200 | || !TEST_ptr(remainder = BN_new())) | |
8d1ebff4 RS |
1201 | goto err; |
1202 | ||
1203 | BN_zero(zero); | |
1204 | ||
30bea14b RS |
1205 | if (!TEST_true(BN_set_word(two, 2)) |
1206 | || !TEST_true(BN_add(ret, a, a)) | |
8d1ebff4 | 1207 | || !equalBN("A + A", lshift1, ret) |
30bea14b | 1208 | || !TEST_true(BN_mul(ret, a, two, ctx)) |
8d1ebff4 | 1209 | || !equalBN("A * 2", lshift1, ret) |
30bea14b | 1210 | || !TEST_true(BN_div(ret, remainder, lshift1, two, ctx)) |
8d1ebff4 RS |
1211 | || !equalBN("LShift1 / 2", a, ret) |
1212 | || !equalBN("LShift1 % 2", zero, remainder) | |
30bea14b | 1213 | || !TEST_true(BN_lshift1(ret, a)) |
8d1ebff4 | 1214 | || !equalBN("A << 1", lshift1, ret) |
30bea14b | 1215 | || !TEST_true(BN_rshift1(ret, lshift1)) |
8d1ebff4 | 1216 | || !equalBN("LShift >> 1", a, ret) |
30bea14b | 1217 | || !TEST_true(BN_rshift1(ret, lshift1)) |
8d1ebff4 RS |
1218 | || !equalBN("LShift >> 1", a, ret)) |
1219 | goto err; | |
1220 | ||
1221 | /* Set the LSB to 1 and test rshift1 again. */ | |
30bea14b RS |
1222 | if (!TEST_true(BN_set_bit(lshift1, 0)) |
1223 | || !TEST_true(BN_div(ret, NULL /* rem */ , lshift1, two, ctx)) | |
8d1ebff4 | 1224 | || !equalBN("(LShift1 | 1) / 2", a, ret) |
30bea14b | 1225 | || !TEST_true(BN_rshift1(ret, lshift1)) |
8d1ebff4 RS |
1226 | || !equalBN("(LShift | 1) >> 1", a, ret)) |
1227 | goto err; | |
1228 | ||
1229 | st = 1; | |
fe16ae5f | 1230 | err: |
8d1ebff4 RS |
1231 | BN_free(a); |
1232 | BN_free(lshift1); | |
1233 | BN_free(zero); | |
1234 | BN_free(ret); | |
1235 | BN_free(two); | |
1236 | BN_free(remainder); | |
1237 | ||
1238 | return st; | |
1239 | } | |
1240 | ||
1241 | static int file_lshift(STANZA *s) | |
1242 | { | |
30bea14b RS |
1243 | BIGNUM *a = NULL, *lshift = NULL, *ret = NULL; |
1244 | int n = 0, st = 0; | |
8d1ebff4 | 1245 | |
30bea14b RS |
1246 | if (!TEST_ptr(a = getBN(s, "A")) |
1247 | || !TEST_ptr(lshift = getBN(s, "LShift")) | |
83ccead4 MC |
1248 | || !TEST_ptr(ret = BN_new()) |
1249 | || !getint(s, &n, "N")) | |
1250 | goto err; | |
8d1ebff4 | 1251 | |
30bea14b | 1252 | if (!TEST_true(BN_lshift(ret, a, n)) |
8d1ebff4 | 1253 | || !equalBN("A << N", lshift, ret) |
30bea14b | 1254 | || !TEST_true(BN_rshift(ret, lshift, n)) |
8d1ebff4 RS |
1255 | || !equalBN("A >> N", a, ret)) |
1256 | goto err; | |
1257 | ||
1258 | st = 1; | |
fe16ae5f | 1259 | err: |
8d1ebff4 RS |
1260 | BN_free(a); |
1261 | BN_free(lshift); | |
1262 | BN_free(ret); | |
1263 | return st; | |
1264 | } | |
1265 | ||
1266 | static int file_rshift(STANZA *s) | |
1267 | { | |
30bea14b RS |
1268 | BIGNUM *a = NULL, *rshift = NULL, *ret = NULL; |
1269 | int n = 0, st = 0; | |
8d1ebff4 | 1270 | |
30bea14b RS |
1271 | if (!TEST_ptr(a = getBN(s, "A")) |
1272 | || !TEST_ptr(rshift = getBN(s, "RShift")) | |
1273 | || !TEST_ptr(ret = BN_new()) | |
1274 | || !getint(s, &n, "N")) | |
8d1ebff4 RS |
1275 | goto err; |
1276 | ||
30bea14b | 1277 | if (!TEST_true(BN_rshift(ret, a, n)) |
8d1ebff4 | 1278 | || !equalBN("A >> N", rshift, ret)) |
30bea14b | 1279 | goto err; |
ceac1975 RL |
1280 | |
1281 | /* If N == 1, try with rshift1 as well */ | |
1282 | if (n == 1) { | |
30bea14b | 1283 | if (!TEST_true(BN_rshift1(ret, a)) |
ceac1975 | 1284 | || !equalBN("A >> 1 (rshift1)", rshift, ret)) |
30bea14b | 1285 | goto err; |
ceac1975 | 1286 | } |
30bea14b | 1287 | st = 1; |
8d1ebff4 | 1288 | |
fe16ae5f | 1289 | err: |
8d1ebff4 RS |
1290 | BN_free(a); |
1291 | BN_free(rshift); | |
1292 | BN_free(ret); | |
30bea14b | 1293 | return st; |
8d1ebff4 RS |
1294 | } |
1295 | ||
1296 | static int file_square(STANZA *s) | |
1297 | { | |
30bea14b RS |
1298 | BIGNUM *a = NULL, *square = NULL, *zero = NULL, *ret = NULL; |
1299 | BIGNUM *remainder = NULL, *tmp = NULL; | |
8d1ebff4 RS |
1300 | int st = 0; |
1301 | ||
30bea14b RS |
1302 | if (!TEST_ptr(a = getBN(s, "A")) |
1303 | || !TEST_ptr(square = getBN(s, "Square")) | |
1304 | || !TEST_ptr(zero = BN_new()) | |
1305 | || !TEST_ptr(ret = BN_new()) | |
1306 | || !TEST_ptr(remainder = BN_new())) | |
8d1ebff4 RS |
1307 | goto err; |
1308 | ||
1309 | BN_zero(zero); | |
30bea14b | 1310 | if (!TEST_true(BN_sqr(ret, a, ctx)) |
8d1ebff4 | 1311 | || !equalBN("A^2", square, ret) |
30bea14b | 1312 | || !TEST_true(BN_mul(ret, a, a, ctx)) |
8d1ebff4 | 1313 | || !equalBN("A * A", square, ret) |
30bea14b | 1314 | || !TEST_true(BN_div(ret, remainder, square, a, ctx)) |
8d1ebff4 RS |
1315 | || !equalBN("Square / A", a, ret) |
1316 | || !equalBN("Square % A", zero, remainder)) | |
1317 | goto err; | |
1318 | ||
1319 | #if HAVE_BN_SQRT | |
1320 | BN_set_negative(a, 0); | |
30bea14b | 1321 | if (!TEST_true(BN_sqrt(ret, square, ctx)) |
8d1ebff4 RS |
1322 | || !equalBN("sqrt(Square)", a, ret)) |
1323 | goto err; | |
1324 | ||
1325 | /* BN_sqrt should fail on non-squares and negative numbers. */ | |
dc352c19 P |
1326 | if (!TEST_BN_eq_zero(square)) { |
1327 | if (!TEST_ptr(tmp = BN_new()) | |
1328 | || !TEST_true(BN_copy(tmp, square))) | |
8d1ebff4 RS |
1329 | goto err; |
1330 | BN_set_negative(tmp, 1); | |
1331 | ||
30bea14b | 1332 | if (!TEST_int_eq(BN_sqrt(ret, tmp, ctx), 0)) |
8d1ebff4 | 1333 | goto err; |
8d1ebff4 RS |
1334 | ERR_clear_error(); |
1335 | ||
1336 | BN_set_negative(tmp, 0); | |
1337 | if (BN_add(tmp, tmp, BN_value_one())) | |
1338 | goto err; | |
30bea14b | 1339 | if (!TEST_int_eq(BN_sqrt(ret, tmp, ctx))) |
8d1ebff4 | 1340 | goto err; |
8d1ebff4 RS |
1341 | ERR_clear_error(); |
1342 | } | |
1343 | #endif | |
1344 | ||
1345 | st = 1; | |
fe16ae5f | 1346 | err: |
8d1ebff4 RS |
1347 | BN_free(a); |
1348 | BN_free(square); | |
1349 | BN_free(zero); | |
1350 | BN_free(ret); | |
1351 | BN_free(remainder); | |
1352 | BN_free(tmp); | |
1353 | return st; | |
1354 | } | |
1355 | ||
1356 | static int file_product(STANZA *s) | |
1357 | { | |
30bea14b RS |
1358 | BIGNUM *a = NULL, *b = NULL, *product = NULL, *ret = NULL; |
1359 | BIGNUM *remainder = NULL, *zero = NULL; | |
8d1ebff4 RS |
1360 | int st = 0; |
1361 | ||
30bea14b RS |
1362 | if (!TEST_ptr(a = getBN(s, "A")) |
1363 | || !TEST_ptr(b = getBN(s, "B")) | |
1364 | || !TEST_ptr(product = getBN(s, "Product")) | |
1365 | || !TEST_ptr(ret = BN_new()) | |
1366 | || !TEST_ptr(remainder = BN_new()) | |
1367 | || !TEST_ptr(zero = BN_new())) | |
8d1ebff4 RS |
1368 | goto err; |
1369 | ||
1370 | BN_zero(zero); | |
1371 | ||
30bea14b | 1372 | if (!TEST_true(BN_mul(ret, a, b, ctx)) |
8d1ebff4 | 1373 | || !equalBN("A * B", product, ret) |
30bea14b | 1374 | || !TEST_true(BN_div(ret, remainder, product, a, ctx)) |
8d1ebff4 RS |
1375 | || !equalBN("Product / A", b, ret) |
1376 | || !equalBN("Product % A", zero, remainder) | |
30bea14b | 1377 | || !TEST_true(BN_div(ret, remainder, product, b, ctx)) |
8d1ebff4 RS |
1378 | || !equalBN("Product / B", a, ret) |
1379 | || !equalBN("Product % B", zero, remainder)) | |
1380 | goto err; | |
1381 | ||
1382 | st = 1; | |
fe16ae5f | 1383 | err: |
8d1ebff4 RS |
1384 | BN_free(a); |
1385 | BN_free(b); | |
1386 | BN_free(product); | |
1387 | BN_free(ret); | |
1388 | BN_free(remainder); | |
1389 | BN_free(zero); | |
1390 | return st; | |
1391 | } | |
1392 | ||
1393 | static int file_quotient(STANZA *s) | |
1394 | { | |
30bea14b RS |
1395 | BIGNUM *a = NULL, *b = NULL, *quotient = NULL, *remainder = NULL; |
1396 | BIGNUM *ret = NULL, *ret2 = NULL, *nnmod = NULL; | |
8d1ebff4 RS |
1397 | BN_ULONG b_word, ret_word; |
1398 | int st = 0; | |
1399 | ||
30bea14b RS |
1400 | if (!TEST_ptr(a = getBN(s, "A")) |
1401 | || !TEST_ptr(b = getBN(s, "B")) | |
1402 | || !TEST_ptr(quotient = getBN(s, "Quotient")) | |
1403 | || !TEST_ptr(remainder = getBN(s, "Remainder")) | |
1404 | || !TEST_ptr(ret = BN_new()) | |
1405 | || !TEST_ptr(ret2 = BN_new()) | |
1406 | || !TEST_ptr(nnmod = BN_new())) | |
8d1ebff4 RS |
1407 | goto err; |
1408 | ||
30bea14b | 1409 | if (!TEST_true(BN_div(ret, ret2, a, b, ctx)) |
8d1ebff4 RS |
1410 | || !equalBN("A / B", quotient, ret) |
1411 | || !equalBN("A % B", remainder, ret2) | |
30bea14b RS |
1412 | || !TEST_true(BN_mul(ret, quotient, b, ctx)) |
1413 | || !TEST_true(BN_add(ret, ret, remainder)) | |
8d1ebff4 RS |
1414 | || !equalBN("Quotient * B + Remainder", a, ret)) |
1415 | goto err; | |
1416 | ||
1417 | /* | |
1418 | * Test with BN_mod_word() and BN_div_word() if the divisor is | |
1419 | * small enough. | |
1420 | */ | |
1421 | b_word = BN_get_word(b); | |
1422 | if (!BN_is_negative(b) && b_word != (BN_ULONG)-1) { | |
1423 | BN_ULONG remainder_word = BN_get_word(remainder); | |
1424 | ||
1425 | assert(remainder_word != (BN_ULONG)-1); | |
30bea14b | 1426 | if (!TEST_ptr(BN_copy(ret, a))) |
8d1ebff4 RS |
1427 | goto err; |
1428 | ret_word = BN_div_word(ret, b_word); | |
1429 | if (ret_word != remainder_word) { | |
1430 | #ifdef BN_DEC_FMT1 | |
30bea14b RS |
1431 | TEST_error( |
1432 | "Got A %% B (word) = " BN_DEC_FMT1 ", wanted " BN_DEC_FMT1, | |
8d1ebff4 RS |
1433 | ret_word, remainder_word); |
1434 | #else | |
30bea14b | 1435 | TEST_error("Got A %% B (word) mismatch"); |
8d1ebff4 RS |
1436 | #endif |
1437 | goto err; | |
1438 | } | |
1439 | if (!equalBN ("A / B (word)", quotient, ret)) | |
1440 | goto err; | |
1441 | ||
1442 | ret_word = BN_mod_word(a, b_word); | |
1443 | if (ret_word != remainder_word) { | |
1444 | #ifdef BN_DEC_FMT1 | |
30bea14b RS |
1445 | TEST_error( |
1446 | "Got A %% B (word) = " BN_DEC_FMT1 ", wanted " BN_DEC_FMT1 "", | |
8d1ebff4 RS |
1447 | ret_word, remainder_word); |
1448 | #else | |
30bea14b | 1449 | TEST_error("Got A %% B (word) mismatch"); |
8d1ebff4 RS |
1450 | #endif |
1451 | goto err; | |
1452 | } | |
1453 | } | |
1454 | ||
1455 | /* Test BN_nnmod. */ | |
1456 | if (!BN_is_negative(b)) { | |
30bea14b RS |
1457 | if (!TEST_true(BN_copy(nnmod, remainder)) |
1458 | || (BN_is_negative(nnmod) | |
1459 | && !TEST_true(BN_add(nnmod, nnmod, b))) | |
1460 | || !TEST_true(BN_nnmod(ret, a, b, ctx)) | |
8d1ebff4 RS |
1461 | || !equalBN("A % B (non-negative)", nnmod, ret)) |
1462 | goto err; | |
1463 | } | |
1464 | ||
1465 | st = 1; | |
fe16ae5f | 1466 | err: |
8d1ebff4 RS |
1467 | BN_free(a); |
1468 | BN_free(b); | |
1469 | BN_free(quotient); | |
1470 | BN_free(remainder); | |
1471 | BN_free(ret); | |
1472 | BN_free(ret2); | |
1473 | BN_free(nnmod); | |
1474 | return st; | |
1475 | } | |
1476 | ||
1477 | static int file_modmul(STANZA *s) | |
1478 | { | |
30bea14b | 1479 | BIGNUM *a = NULL, *b = NULL, *m = NULL, *mod_mul = NULL, *ret = NULL; |
8d1ebff4 RS |
1480 | int st = 0; |
1481 | ||
30bea14b RS |
1482 | if (!TEST_ptr(a = getBN(s, "A")) |
1483 | || !TEST_ptr(b = getBN(s, "B")) | |
1484 | || !TEST_ptr(m = getBN(s, "M")) | |
1485 | || !TEST_ptr(mod_mul = getBN(s, "ModMul")) | |
1486 | || !TEST_ptr(ret = BN_new())) | |
8d1ebff4 RS |
1487 | goto err; |
1488 | ||
30bea14b | 1489 | if (!TEST_true(BN_mod_mul(ret, a, b, m, ctx)) |
8d1ebff4 RS |
1490 | || !equalBN("A * B (mod M)", mod_mul, ret)) |
1491 | goto err; | |
1492 | ||
1493 | if (BN_is_odd(m)) { | |
1494 | /* Reduce |a| and |b| and test the Montgomery version. */ | |
1495 | BN_MONT_CTX *mont = BN_MONT_CTX_new(); | |
1496 | BIGNUM *a_tmp = BN_new(); | |
1497 | BIGNUM *b_tmp = BN_new(); | |
30bea14b | 1498 | |
8d1ebff4 | 1499 | if (mont == NULL || a_tmp == NULL || b_tmp == NULL |
30bea14b RS |
1500 | || !TEST_true(BN_MONT_CTX_set(mont, m, ctx)) |
1501 | || !TEST_true(BN_nnmod(a_tmp, a, m, ctx)) | |
1502 | || !TEST_true(BN_nnmod(b_tmp, b, m, ctx)) | |
1503 | || !TEST_true(BN_to_montgomery(a_tmp, a_tmp, mont, ctx)) | |
1504 | || !TEST_true(BN_to_montgomery(b_tmp, b_tmp, mont, ctx)) | |
1505 | || !TEST_true(BN_mod_mul_montgomery(ret, a_tmp, b_tmp, | |
1506 | mont, ctx)) | |
1507 | || !TEST_true(BN_from_montgomery(ret, ret, mont, ctx)) | |
1508 | || !equalBN("A * B (mod M) (mont)", mod_mul, ret)) | |
8d1ebff4 | 1509 | st = 0; |
30bea14b | 1510 | else |
8d1ebff4 | 1511 | st = 1; |
8d1ebff4 RS |
1512 | BN_MONT_CTX_free(mont); |
1513 | BN_free(a_tmp); | |
1514 | BN_free(b_tmp); | |
1515 | if (st == 0) | |
1516 | goto err; | |
1517 | } | |
1518 | ||
1519 | st = 1; | |
fe16ae5f | 1520 | err: |
8d1ebff4 RS |
1521 | BN_free(a); |
1522 | BN_free(b); | |
1523 | BN_free(m); | |
1524 | BN_free(mod_mul); | |
1525 | BN_free(ret); | |
1526 | return st; | |
1527 | } | |
1528 | ||
1529 | static int file_modexp(STANZA *s) | |
1530 | { | |
30bea14b RS |
1531 | BIGNUM *a = NULL, *e = NULL, *m = NULL, *mod_exp = NULL, *ret = NULL; |
1532 | BIGNUM *b = NULL, *c = NULL, *d = NULL; | |
8d1ebff4 RS |
1533 | int st = 0; |
1534 | ||
30bea14b RS |
1535 | if (!TEST_ptr(a = getBN(s, "A")) |
1536 | || !TEST_ptr(e = getBN(s, "E")) | |
1537 | || !TEST_ptr(m = getBN(s, "M")) | |
1538 | || !TEST_ptr(mod_exp = getBN(s, "ModExp")) | |
1539 | || !TEST_ptr(ret = BN_new()) | |
1540 | || !TEST_ptr(d = BN_new())) | |
8d1ebff4 RS |
1541 | goto err; |
1542 | ||
30bea14b | 1543 | if (!TEST_true(BN_mod_exp(ret, a, e, m, ctx)) |
8d1ebff4 RS |
1544 | || !equalBN("A ^ E (mod M)", mod_exp, ret)) |
1545 | goto err; | |
1546 | ||
1547 | if (BN_is_odd(m)) { | |
30bea14b | 1548 | if (!TEST_true(BN_mod_exp_mont(ret, a, e, m, ctx, NULL)) |
8d1ebff4 | 1549 | || !equalBN("A ^ E (mod M) (mont)", mod_exp, ret) |
30bea14b RS |
1550 | || !TEST_true(BN_mod_exp_mont_consttime(ret, a, e, m, |
1551 | ctx, NULL)) | |
8d1ebff4 RS |
1552 | || !equalBN("A ^ E (mod M) (mont const", mod_exp, ret)) |
1553 | goto err; | |
1554 | } | |
1555 | ||
1556 | /* Regression test for carry propagation bug in sqr8x_reduction */ | |
1557 | BN_hex2bn(&a, "050505050505"); | |
1558 | BN_hex2bn(&b, "02"); | |
1559 | BN_hex2bn(&c, | |
1560 | "4141414141414141414141274141414141414141414141414141414141414141" | |
1561 | "4141414141414141414141414141414141414141414141414141414141414141" | |
1562 | "4141414141414141414141800000000000000000000000000000000000000000" | |
1563 | "0000000000000000000000000000000000000000000000000000000000000000" | |
1564 | "0000000000000000000000000000000000000000000000000000000000000000" | |
1565 | "0000000000000000000000000000000000000000000000000000000001"); | |
9e206ce5 P |
1566 | if (!TEST_true(BN_mod_exp(d, a, b, c, ctx)) |
1567 | || !TEST_true(BN_mul(e, a, a, ctx)) | |
1568 | || !TEST_BN_eq(d, e)) | |
8d1ebff4 | 1569 | goto err; |
8d1ebff4 RS |
1570 | |
1571 | st = 1; | |
fe16ae5f | 1572 | err: |
8d1ebff4 RS |
1573 | BN_free(a); |
1574 | BN_free(b); | |
1575 | BN_free(c); | |
1576 | BN_free(d); | |
1577 | BN_free(e); | |
1578 | BN_free(m); | |
1579 | BN_free(mod_exp); | |
1580 | BN_free(ret); | |
1581 | return st; | |
1582 | } | |
1583 | ||
1584 | static int file_exp(STANZA *s) | |
1585 | { | |
30bea14b | 1586 | BIGNUM *a = NULL, *e = NULL, *exp = NULL, *ret = NULL; |
8d1ebff4 RS |
1587 | int st = 0; |
1588 | ||
30bea14b RS |
1589 | if (!TEST_ptr(a = getBN(s, "A")) |
1590 | || !TEST_ptr(e = getBN(s, "E")) | |
1591 | || !TEST_ptr(exp = getBN(s, "Exp")) | |
1592 | || !TEST_ptr(ret = BN_new())) | |
8d1ebff4 RS |
1593 | goto err; |
1594 | ||
30bea14b | 1595 | if (!TEST_true(BN_exp(ret, a, e, ctx)) |
8d1ebff4 RS |
1596 | || !equalBN("A ^ E", exp, ret)) |
1597 | goto err; | |
1598 | ||
1599 | st = 1; | |
fe16ae5f | 1600 | err: |
8d1ebff4 RS |
1601 | BN_free(a); |
1602 | BN_free(e); | |
1603 | BN_free(exp); | |
1604 | BN_free(ret); | |
1605 | return st; | |
1606 | } | |
1607 | ||
1608 | static int file_modsqrt(STANZA *s) | |
1609 | { | |
30bea14b | 1610 | BIGNUM *a = NULL, *p = NULL, *mod_sqrt = NULL, *ret = NULL, *ret2 = NULL; |
8d1ebff4 RS |
1611 | int st = 0; |
1612 | ||
30bea14b RS |
1613 | if (!TEST_ptr(a = getBN(s, "A")) |
1614 | || !TEST_ptr(p = getBN(s, "P")) | |
1615 | || !TEST_ptr(mod_sqrt = getBN(s, "ModSqrt")) | |
1616 | || !TEST_ptr(ret = BN_new()) | |
1617 | || !TEST_ptr(ret2 = BN_new())) | |
8d1ebff4 RS |
1618 | goto err; |
1619 | ||
1620 | /* There are two possible answers. */ | |
30bea14b RS |
1621 | if (!TEST_true(BN_mod_sqrt(ret, a, p, ctx)) |
1622 | || !TEST_true(BN_sub(ret2, p, ret))) | |
8d1ebff4 RS |
1623 | goto err; |
1624 | ||
30bea14b | 1625 | /* The first condition should NOT be a test. */ |
8d1ebff4 RS |
1626 | if (BN_cmp(ret2, mod_sqrt) != 0 |
1627 | && !equalBN("sqrt(A) (mod P)", mod_sqrt, ret)) | |
1628 | goto err; | |
1629 | ||
1630 | st = 1; | |
fe16ae5f | 1631 | err: |
8d1ebff4 RS |
1632 | BN_free(a); |
1633 | BN_free(p); | |
1634 | BN_free(mod_sqrt); | |
1635 | BN_free(ret); | |
1636 | BN_free(ret2); | |
1637 | return st; | |
1638 | } | |
1639 | ||
b75d6310 CPG |
1640 | static int file_gcd(STANZA *s) |
1641 | { | |
1642 | BIGNUM *a = NULL, *b = NULL, *gcd = NULL, *ret = NULL; | |
1643 | int st = 0; | |
1644 | ||
1645 | if (!TEST_ptr(a = getBN(s, "A")) | |
1646 | || !TEST_ptr(b = getBN(s, "B")) | |
1647 | || !TEST_ptr(gcd = getBN(s, "GCD")) | |
1648 | || !TEST_ptr(ret = BN_new())) | |
1649 | goto err; | |
1650 | ||
1651 | if (!TEST_true(BN_gcd(ret, a, b, ctx)) | |
1652 | || !equalBN("gcd(A,B)", gcd, ret)) | |
1653 | goto err; | |
1654 | ||
1655 | st = 1; | |
1656 | err: | |
1657 | BN_free(a); | |
1658 | BN_free(b); | |
1659 | BN_free(gcd); | |
1660 | BN_free(ret); | |
1661 | return st; | |
1662 | } | |
1663 | ||
31a80694 | 1664 | static int test_bn2padded(void) |
8d1ebff4 RS |
1665 | { |
1666 | #if HAVE_BN_PADDED | |
1667 | uint8_t zeros[256], out[256], reference[128]; | |
1668 | BIGNUM *n = BN_new(); | |
1669 | int st = 0; | |
1670 | ||
1671 | /* Test edge case at 0. */ | |
1672 | if (n == NULL) | |
1673 | goto err; | |
30bea14b | 1674 | if (!TEST_true(BN_bn2bin_padded(NULL, 0, n))) |
8d1ebff4 | 1675 | goto err; |
8d1ebff4 | 1676 | memset(out, -1, sizeof(out)); |
30bea14b | 1677 | if (!TEST_true(BN_bn2bin_padded(out, sizeof(out)), n)) |
8d1ebff4 | 1678 | goto err; |
8d1ebff4 | 1679 | memset(zeros, 0, sizeof(zeros)); |
30bea14b | 1680 | if (!TEST_mem_eq(zeros, sizeof(zeros), out, sizeof(out))) |
8d1ebff4 | 1681 | goto err; |
8d1ebff4 RS |
1682 | |
1683 | /* Test a random numbers at various byte lengths. */ | |
1684 | for (size_t bytes = 128 - 7; bytes <= 128; bytes++) { | |
fe16ae5f NT |
1685 | # define TOP_BIT_ON 0 |
1686 | # define BOTTOM_BIT_NOTOUCH 0 | |
30bea14b | 1687 | if (!TEST_true(BN_rand(n, bytes * 8, TOP_BIT_ON, BOTTOM_BIT_NOTOUCH))) |
8d1ebff4 | 1688 | goto err; |
30bea14b RS |
1689 | if (!TEST_int_eq(BN_num_bytes(n),A) bytes |
1690 | || TEST_int_eq(BN_bn2bin(n, reference), bytes)) | |
8d1ebff4 | 1691 | goto err; |
8d1ebff4 | 1692 | /* Empty buffer should fail. */ |
30bea14b | 1693 | if (!TEST_int_eq(BN_bn2bin_padded(NULL, 0, n)), 0) |
8d1ebff4 | 1694 | goto err; |
8d1ebff4 | 1695 | /* One byte short should fail. */ |
30bea14b | 1696 | if (BN_bn2bin_padded(out, bytes - 1, n)) |
8d1ebff4 | 1697 | goto err; |
8d1ebff4 | 1698 | /* Exactly right size should encode. */ |
30bea14b RS |
1699 | if (!TEST_true(BN_bn2bin_padded(out, bytes, n)) |
1700 | || TEST_mem_eq(out, bytes, reference, bytes)) | |
8d1ebff4 | 1701 | goto err; |
8d1ebff4 | 1702 | /* Pad up one byte extra. */ |
30bea14b RS |
1703 | if (!TEST_true(BN_bn2bin_padded(out, bytes + 1, n)) |
1704 | || !TEST_mem_eq(out + 1, bytes, reference, bytes) | |
1705 | || !TEST_mem_eq(out, 1, zeros, 1)) | |
8d1ebff4 | 1706 | goto err; |
8d1ebff4 | 1707 | /* Pad up to 256. */ |
30bea14b RS |
1708 | if (!TEST_true(BN_bn2bin_padded(out, sizeof(out)), n) |
1709 | || !TEST_mem_eq(out + sizeof(out) - bytes, bytes, | |
1710 | reference, bytes) | |
1711 | || !TEST_mem_eq(out, sizseof(out) - bytes, | |
1712 | zeros, sizeof(out) - bytes)) | |
8d1ebff4 | 1713 | goto err; |
8d1ebff4 RS |
1714 | } |
1715 | ||
1716 | st = 1; | |
fe16ae5f | 1717 | err: |
8d1ebff4 RS |
1718 | BN_free(n); |
1719 | return st; | |
1720 | #else | |
1721 | return ctx != NULL; | |
1722 | #endif | |
1723 | } | |
1724 | ||
31a80694 | 1725 | static int test_dec2bn(void) |
8d1ebff4 RS |
1726 | { |
1727 | BIGNUM *bn = NULL; | |
1728 | int st = 0; | |
1729 | ||
30bea14b | 1730 | if (!TEST_int_eq(parsedecBN(&bn, "0"), 1) |
dc352c19 P |
1731 | || !TEST_BN_eq_word(bn, 0) |
1732 | || !TEST_BN_eq_zero(bn) | |
1733 | || !TEST_BN_le_zero(bn) | |
1734 | || !TEST_BN_ge_zero(bn) | |
1735 | || !TEST_BN_even(bn)) | |
8d1ebff4 | 1736 | goto err; |
8d1ebff4 | 1737 | BN_free(bn); |
dc352c19 | 1738 | bn = NULL; |
8d1ebff4 | 1739 | |
30bea14b | 1740 | if (!TEST_int_eq(parsedecBN(&bn, "256"), 3) |
dc352c19 P |
1741 | || !TEST_BN_eq_word(bn, 256) |
1742 | || !TEST_BN_ge_zero(bn) | |
1743 | || !TEST_BN_gt_zero(bn) | |
1744 | || !TEST_BN_ne_zero(bn) | |
1745 | || !TEST_BN_even(bn)) | |
8d1ebff4 | 1746 | goto err; |
8d1ebff4 | 1747 | BN_free(bn); |
dc352c19 | 1748 | bn = NULL; |
8d1ebff4 | 1749 | |
30bea14b | 1750 | if (!TEST_int_eq(parsedecBN(&bn, "-42"), 3) |
dc352c19 P |
1751 | || !TEST_BN_abs_eq_word(bn, 42) |
1752 | || !TEST_BN_lt_zero(bn) | |
1753 | || !TEST_BN_le_zero(bn) | |
1754 | || !TEST_BN_ne_zero(bn) | |
1755 | || !TEST_BN_even(bn)) | |
8d1ebff4 | 1756 | goto err; |
8d1ebff4 | 1757 | BN_free(bn); |
dc352c19 P |
1758 | bn = NULL; |
1759 | ||
1760 | if (!TEST_int_eq(parsedecBN(&bn, "1"), 1) | |
1761 | || !TEST_BN_eq_word(bn, 1) | |
1762 | || !TEST_BN_ne_zero(bn) | |
1763 | || !TEST_BN_gt_zero(bn) | |
1764 | || !TEST_BN_ge_zero(bn) | |
1765 | || !TEST_BN_eq_one(bn) | |
1766 | || !TEST_BN_odd(bn)) | |
1767 | goto err; | |
1768 | BN_free(bn); | |
1769 | bn = NULL; | |
8d1ebff4 | 1770 | |
30bea14b | 1771 | if (!TEST_int_eq(parsedecBN(&bn, "-0"), 2) |
dc352c19 P |
1772 | || !TEST_BN_eq_zero(bn) |
1773 | || !TEST_BN_ge_zero(bn) | |
1774 | || !TEST_BN_le_zero(bn) | |
1775 | || !TEST_BN_even(bn)) | |
8d1ebff4 | 1776 | goto err; |
8d1ebff4 | 1777 | BN_free(bn); |
dc352c19 | 1778 | bn = NULL; |
8d1ebff4 | 1779 | |
30bea14b | 1780 | if (!TEST_int_eq(parsedecBN(&bn, "42trailing garbage is ignored"), 2) |
dc352c19 P |
1781 | || !TEST_BN_abs_eq_word(bn, 42) |
1782 | || !TEST_BN_ge_zero(bn) | |
1783 | || !TEST_BN_gt_zero(bn) | |
1784 | || !TEST_BN_ne_zero(bn) | |
1785 | || !TEST_BN_even(bn)) | |
8d1ebff4 | 1786 | goto err; |
8d1ebff4 RS |
1787 | |
1788 | st = 1; | |
fe16ae5f | 1789 | err: |
8d1ebff4 RS |
1790 | BN_free(bn); |
1791 | return st; | |
1792 | } | |
1793 | ||
31a80694 | 1794 | static int test_hex2bn(void) |
8d1ebff4 RS |
1795 | { |
1796 | BIGNUM *bn = NULL; | |
30bea14b | 1797 | int st = 0; |
8d1ebff4 | 1798 | |
30bea14b | 1799 | if (!TEST_int_eq(parseBN(&bn, "0"), 1) |
dc352c19 P |
1800 | || !TEST_BN_eq_zero(bn) |
1801 | || !TEST_BN_ge_zero(bn) | |
1802 | || !TEST_BN_even(bn)) | |
8d1ebff4 | 1803 | goto err; |
8d1ebff4 | 1804 | BN_free(bn); |
dc352c19 | 1805 | bn = NULL; |
8d1ebff4 | 1806 | |
30bea14b | 1807 | if (!TEST_int_eq(parseBN(&bn, "256"), 3) |
dc352c19 P |
1808 | || !TEST_BN_eq_word(bn, 0x256) |
1809 | || !TEST_BN_ge_zero(bn) | |
1810 | || !TEST_BN_gt_zero(bn) | |
1811 | || !TEST_BN_ne_zero(bn) | |
1812 | || !TEST_BN_even(bn)) | |
8d1ebff4 | 1813 | goto err; |
8d1ebff4 | 1814 | BN_free(bn); |
dc352c19 | 1815 | bn = NULL; |
8d1ebff4 | 1816 | |
30bea14b | 1817 | if (!TEST_int_eq(parseBN(&bn, "-42"), 3) |
dc352c19 P |
1818 | || !TEST_BN_abs_eq_word(bn, 0x42) |
1819 | || !TEST_BN_lt_zero(bn) | |
1820 | || !TEST_BN_le_zero(bn) | |
1821 | || !TEST_BN_ne_zero(bn) | |
1822 | || !TEST_BN_even(bn)) | |
1823 | goto err; | |
1824 | BN_free(bn); | |
1825 | bn = NULL; | |
1826 | ||
1827 | if (!TEST_int_eq(parseBN(&bn, "cb"), 2) | |
1828 | || !TEST_BN_eq_word(bn, 0xCB) | |
1829 | || !TEST_BN_ge_zero(bn) | |
1830 | || !TEST_BN_gt_zero(bn) | |
1831 | || !TEST_BN_ne_zero(bn) | |
1832 | || !TEST_BN_odd(bn)) | |
8d1ebff4 | 1833 | goto err; |
8d1ebff4 | 1834 | BN_free(bn); |
dc352c19 | 1835 | bn = NULL; |
8d1ebff4 | 1836 | |
30bea14b | 1837 | if (!TEST_int_eq(parseBN(&bn, "-0"), 2) |
dc352c19 P |
1838 | || !TEST_BN_eq_zero(bn) |
1839 | || !TEST_BN_ge_zero(bn) | |
1840 | || !TEST_BN_le_zero(bn) | |
1841 | || !TEST_BN_even(bn)) | |
8d1ebff4 | 1842 | goto err; |
8d1ebff4 | 1843 | BN_free(bn); |
dc352c19 | 1844 | bn = NULL; |
8d1ebff4 | 1845 | |
30bea14b | 1846 | if (!TEST_int_eq(parseBN(&bn, "abctrailing garbage is ignored"), 3) |
dc352c19 P |
1847 | || !TEST_BN_eq_word(bn, 0xabc) |
1848 | || !TEST_BN_ge_zero(bn) | |
1849 | || !TEST_BN_gt_zero(bn) | |
1850 | || !TEST_BN_ne_zero(bn) | |
1851 | || !TEST_BN_even(bn)) | |
8d1ebff4 | 1852 | goto err; |
8d1ebff4 RS |
1853 | st = 1; |
1854 | ||
fe16ae5f | 1855 | err: |
8d1ebff4 RS |
1856 | BN_free(bn); |
1857 | return st; | |
1858 | } | |
1859 | ||
31a80694 | 1860 | static int test_asc2bn(void) |
8d1ebff4 | 1861 | { |
30bea14b | 1862 | BIGNUM *bn = NULL; |
8d1ebff4 RS |
1863 | int st = 0; |
1864 | ||
30bea14b | 1865 | if (!TEST_ptr(bn = BN_new())) |
8d1ebff4 | 1866 | goto err; |
8d1ebff4 | 1867 | |
30bea14b | 1868 | if (!TEST_true(BN_asc2bn(&bn, "0")) |
dc352c19 P |
1869 | || !TEST_BN_eq_zero(bn) |
1870 | || !TEST_BN_ge_zero(bn)) | |
8d1ebff4 | 1871 | goto err; |
8d1ebff4 | 1872 | |
30bea14b | 1873 | if (!TEST_true(BN_asc2bn(&bn, "256")) |
dc352c19 P |
1874 | || !TEST_BN_eq_word(bn, 256) |
1875 | || !TEST_BN_ge_zero(bn)) | |
8d1ebff4 | 1876 | goto err; |
8d1ebff4 | 1877 | |
30bea14b | 1878 | if (!TEST_true(BN_asc2bn(&bn, "-42")) |
dc352c19 P |
1879 | || !TEST_BN_abs_eq_word(bn, 42) |
1880 | || !TEST_BN_lt_zero(bn)) | |
8d1ebff4 | 1881 | goto err; |
8d1ebff4 | 1882 | |
30bea14b | 1883 | if (!TEST_true(BN_asc2bn(&bn, "0x1234")) |
dc352c19 P |
1884 | || !TEST_BN_eq_word(bn, 0x1234) |
1885 | || !TEST_BN_ge_zero(bn)) | |
8d1ebff4 | 1886 | goto err; |
8d1ebff4 | 1887 | |
30bea14b | 1888 | if (!TEST_true(BN_asc2bn(&bn, "0X1234")) |
dc352c19 P |
1889 | || !TEST_BN_eq_word(bn, 0x1234) |
1890 | || !TEST_BN_ge_zero(bn)) | |
8d1ebff4 | 1891 | goto err; |
8d1ebff4 | 1892 | |
30bea14b | 1893 | if (!TEST_true(BN_asc2bn(&bn, "-0xabcd")) |
dc352c19 P |
1894 | || !TEST_BN_abs_eq_word(bn, 0xabcd) |
1895 | || !TEST_BN_lt_zero(bn)) | |
8d1ebff4 | 1896 | goto err; |
8d1ebff4 | 1897 | |
30bea14b | 1898 | if (!TEST_true(BN_asc2bn(&bn, "-0")) |
dc352c19 P |
1899 | || !TEST_BN_eq_zero(bn) |
1900 | || !TEST_BN_ge_zero(bn)) | |
30bea14b RS |
1901 | goto err; |
1902 | ||
1903 | if (!TEST_true(BN_asc2bn(&bn, "123trailing garbage is ignored")) | |
dc352c19 P |
1904 | || !TEST_BN_eq_word(bn, 123) |
1905 | || !TEST_BN_ge_zero(bn)) | |
8d1ebff4 | 1906 | goto err; |
8d1ebff4 RS |
1907 | |
1908 | st = 1; | |
fe16ae5f | 1909 | err: |
8d1ebff4 RS |
1910 | BN_free(bn); |
1911 | return st; | |
1912 | } | |
1913 | ||
1914 | static const MPITEST kMPITests[] = { | |
1915 | {"0", "\x00\x00\x00\x00", 4}, | |
1916 | {"1", "\x00\x00\x00\x01\x01", 5}, | |
1917 | {"-1", "\x00\x00\x00\x01\x81", 5}, | |
1918 | {"128", "\x00\x00\x00\x02\x00\x80", 6}, | |
1919 | {"256", "\x00\x00\x00\x02\x01\x00", 6}, | |
1920 | {"-256", "\x00\x00\x00\x02\x81\x00", 6}, | |
1921 | }; | |
1922 | ||
30bea14b | 1923 | static int test_mpi(int i) |
8d1ebff4 RS |
1924 | { |
1925 | uint8_t scratch[8]; | |
30bea14b | 1926 | const MPITEST *test = &kMPITests[i]; |
8d1ebff4 | 1927 | size_t mpi_len, mpi_len2; |
30bea14b | 1928 | BIGNUM *bn = NULL; |
8d1ebff4 RS |
1929 | BIGNUM *bn2 = NULL; |
1930 | int st = 0; | |
1931 | ||
30bea14b RS |
1932 | if (!TEST_ptr(bn = BN_new()) |
1933 | || !TEST_true(BN_asc2bn(&bn, test->base10))) | |
1934 | goto err; | |
1935 | mpi_len = BN_bn2mpi(bn, NULL); | |
1936 | if (!TEST_size_t_le(mpi_len, sizeof(scratch))) | |
1937 | goto err; | |
8d1ebff4 | 1938 | |
30bea14b RS |
1939 | if (!TEST_size_t_eq(mpi_len2 = BN_bn2mpi(bn, scratch), mpi_len) |
1940 | || !TEST_mem_eq(test->mpi, test->mpi_len, scratch, mpi_len)) | |
1941 | goto err; | |
8d1ebff4 | 1942 | |
30bea14b RS |
1943 | if (!TEST_ptr(bn2 = BN_mpi2bn(scratch, mpi_len, NULL))) |
1944 | goto err; | |
8d1ebff4 | 1945 | |
dc352c19 | 1946 | if (!TEST_BN_eq(bn, bn2)) { |
8d1ebff4 | 1947 | BN_free(bn2); |
30bea14b | 1948 | goto err; |
8d1ebff4 | 1949 | } |
30bea14b | 1950 | BN_free(bn2); |
8d1ebff4 RS |
1951 | |
1952 | st = 1; | |
fe16ae5f | 1953 | err: |
8d1ebff4 RS |
1954 | BN_free(bn); |
1955 | return st; | |
0f113f3e | 1956 | } |
bdec3c53 | 1957 | |
31a80694 | 1958 | static int test_rand(void) |
0f113f3e | 1959 | { |
30bea14b | 1960 | BIGNUM *bn = NULL; |
8d1ebff4 | 1961 | int st = 0; |
0f113f3e | 1962 | |
30bea14b | 1963 | if (!TEST_ptr(bn = BN_new())) |
8d1ebff4 | 1964 | return 0; |
0f113f3e | 1965 | |
30bea14b RS |
1966 | /* Test BN_rand for degenerate cases with |top| and |bottom| parameters. */ |
1967 | if (!TEST_false(BN_rand(bn, 0, 0 /* top */ , 0 /* bottom */ )) | |
1968 | || !TEST_false(BN_rand(bn, 0, 1 /* top */ , 1 /* bottom */ )) | |
1969 | || !TEST_true(BN_rand(bn, 1, 0 /* top */ , 0 /* bottom */ )) | |
dc352c19 | 1970 | || !TEST_BN_eq_one(bn) |
30bea14b RS |
1971 | || !TEST_false(BN_rand(bn, 1, 1 /* top */ , 0 /* bottom */ )) |
1972 | || !TEST_true(BN_rand(bn, 1, -1 /* top */ , 1 /* bottom */ )) | |
dc352c19 | 1973 | || !TEST_BN_eq_one(bn) |
30bea14b | 1974 | || !TEST_true(BN_rand(bn, 2, 1 /* top */ , 0 /* bottom */ )) |
dc352c19 | 1975 | || !TEST_BN_eq_word(bn, 3)) |
8d1ebff4 | 1976 | goto err; |
0f113f3e | 1977 | |
8d1ebff4 | 1978 | st = 1; |
fe16ae5f | 1979 | err: |
8d1ebff4 RS |
1980 | BN_free(bn); |
1981 | return st; | |
1982 | } | |
1983 | ||
bb5b3e6d P |
1984 | /* |
1985 | * Run some statistical tests to provide a degree confidence that the | |
5d2f3e4a P |
1986 | * BN_rand_range() function works as expected. The test cases and |
1987 | * critical values are generated by the bn_rand_range script. | |
bb5b3e6d | 1988 | * |
5d2f3e4a P |
1989 | * Each individual test is a Chi^2 goodness of fit for a specified number |
1990 | * of samples and range. The samples are assumed to be independent and | |
1991 | * that they are from a discrete uniform distribution. | |
bb5b3e6d | 1992 | * |
5d2f3e4a P |
1993 | * Some of these individual tests are expected to fail, the success/failure |
1994 | * of each is an independent Bernoulli trial. The number of such successes | |
1995 | * will form a binomial distribution. The count of the successes is compared | |
1996 | * against a precomputed critical value to determine the overall outcome. | |
bb5b3e6d | 1997 | */ |
5d2f3e4a | 1998 | struct rand_range_case { |
bb5b3e6d P |
1999 | unsigned int range; |
2000 | unsigned int iterations; | |
2001 | double critical; | |
bb5b3e6d P |
2002 | }; |
2003 | ||
5d2f3e4a P |
2004 | #include "bn_rand_range.h" |
2005 | ||
2006 | static int test_rand_range_single(size_t n) | |
bb5b3e6d P |
2007 | { |
2008 | const unsigned int range = rand_range_cases[n].range; | |
2009 | const unsigned int iterations = rand_range_cases[n].iterations; | |
2010 | const double critical = rand_range_cases[n].critical; | |
2011 | const double expected = iterations / (double)range; | |
2012 | double sum = 0; | |
2013 | BIGNUM *rng = NULL, *val = NULL; | |
2014 | size_t *counts; | |
2015 | unsigned int i, v; | |
2016 | int res = 0; | |
2017 | ||
2018 | if (!TEST_ptr(counts = OPENSSL_zalloc(sizeof(*counts) * range)) | |
2019 | || !TEST_ptr(rng = BN_new()) | |
2020 | || !TEST_ptr(val = BN_new()) | |
2021 | || !TEST_true(BN_set_word(rng, range))) | |
2022 | goto err; | |
2023 | for (i = 0; i < iterations; i++) { | |
2024 | if (!TEST_true(BN_rand_range(val, rng)) | |
2025 | || !TEST_uint_lt(v = (unsigned int)BN_get_word(val), range)) | |
2026 | goto err; | |
2027 | counts[v]++; | |
2028 | } | |
2029 | ||
bb5b3e6d P |
2030 | for (i = 0; i < range; i++) { |
2031 | const double delta = counts[i] - expected; | |
2032 | sum += delta * delta; | |
2033 | } | |
2034 | sum /= expected; | |
bb5b3e6d | 2035 | |
5d2f3e4a P |
2036 | if (sum > critical) { |
2037 | TEST_info("Chi^2 test negative %.4f > %4.f", sum, critical); | |
2038 | TEST_note("test case %zu range %u iterations %u", n + 1, range, | |
2039 | iterations); | |
2040 | goto err; | |
2041 | } | |
2042 | ||
2043 | res = 1; | |
bb5b3e6d P |
2044 | err: |
2045 | BN_free(rng); | |
2046 | BN_free(val); | |
2047 | OPENSSL_free(counts); | |
2048 | return res; | |
2049 | } | |
2050 | ||
5d2f3e4a P |
2051 | static int test_rand_range(void) |
2052 | { | |
2053 | int n_success = 0; | |
2054 | size_t i; | |
2055 | ||
2056 | for (i = 0; i < OSSL_NELEM(rand_range_cases); i++) | |
2057 | n_success += test_rand_range_single(i); | |
2058 | if (TEST_int_ge(n_success, binomial_critical)) | |
2059 | return 1; | |
79c44b4e | 2060 | TEST_note("This test is expected to fail by chance 0.01%% of the time."); |
5d2f3e4a P |
2061 | return 0; |
2062 | } | |
2063 | ||
31a80694 | 2064 | static int test_negzero(void) |
8d1ebff4 | 2065 | { |
30bea14b | 2066 | BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL; |
8d1ebff4 RS |
2067 | BIGNUM *numerator = NULL, *denominator = NULL; |
2068 | int consttime, st = 0; | |
2069 | ||
30bea14b RS |
2070 | if (!TEST_ptr(a = BN_new()) |
2071 | || !TEST_ptr(b = BN_new()) | |
2072 | || !TEST_ptr(c = BN_new()) | |
2073 | || !TEST_ptr(d = BN_new())) | |
8d1ebff4 RS |
2074 | goto err; |
2075 | ||
2076 | /* Test that BN_mul never gives negative zero. */ | |
30bea14b | 2077 | if (!TEST_true(BN_set_word(a, 1))) |
8d1ebff4 RS |
2078 | goto err; |
2079 | BN_set_negative(a, 1); | |
2080 | BN_zero(b); | |
30bea14b | 2081 | if (!TEST_true(BN_mul(c, a, b, ctx))) |
8d1ebff4 | 2082 | goto err; |
dc352c19 P |
2083 | if (!TEST_BN_eq_zero(c) |
2084 | || !TEST_BN_ge_zero(c)) | |
8d1ebff4 | 2085 | goto err; |
8d1ebff4 RS |
2086 | |
2087 | for (consttime = 0; consttime < 2; consttime++) { | |
30bea14b RS |
2088 | if (!TEST_ptr(numerator = BN_new()) |
2089 | || !TEST_ptr(denominator = BN_new())) | |
0f113f3e | 2090 | goto err; |
8d1ebff4 RS |
2091 | if (consttime) { |
2092 | BN_set_flags(numerator, BN_FLG_CONSTTIME); | |
2093 | BN_set_flags(denominator, BN_FLG_CONSTTIME); | |
2094 | } | |
2095 | /* Test that BN_div never gives negative zero in the quotient. */ | |
30bea14b RS |
2096 | if (!TEST_true(BN_set_word(numerator, 1)) |
2097 | || !TEST_true(BN_set_word(denominator, 2))) | |
0f113f3e | 2098 | goto err; |
8d1ebff4 | 2099 | BN_set_negative(numerator, 1); |
30bea14b | 2100 | if (!TEST_true(BN_div(a, b, numerator, denominator, ctx)) |
dc352c19 P |
2101 | || !TEST_BN_eq_zero(a) |
2102 | || !TEST_BN_ge_zero(a)) | |
0f113f3e | 2103 | goto err; |
0f113f3e | 2104 | |
8d1ebff4 | 2105 | /* Test that BN_div never gives negative zero in the remainder. */ |
30bea14b RS |
2106 | if (!TEST_true(BN_set_word(denominator, 1)) |
2107 | || !TEST_true(BN_div(a, b, numerator, denominator, ctx)) | |
dc352c19 P |
2108 | || !TEST_BN_eq_zero(b) |
2109 | || !TEST_BN_ge_zero(b)) | |
0f113f3e | 2110 | goto err; |
8d1ebff4 RS |
2111 | BN_free(numerator); |
2112 | BN_free(denominator); | |
2113 | numerator = denominator = NULL; | |
2114 | } | |
0f113f3e | 2115 | |
8d1ebff4 RS |
2116 | /* Test that BN_set_negative will not produce a negative zero. */ |
2117 | BN_zero(a); | |
2118 | BN_set_negative(a, 1); | |
30bea14b | 2119 | if (BN_is_negative(a)) |
8d1ebff4 | 2120 | goto err; |
8d1ebff4 | 2121 | st = 1; |
30bea14b | 2122 | |
fe16ae5f | 2123 | err: |
23a1d5e9 RS |
2124 | BN_free(a); |
2125 | BN_free(b); | |
8d1ebff4 RS |
2126 | BN_free(c); |
2127 | BN_free(d); | |
2128 | BN_free(numerator); | |
2129 | BN_free(denominator); | |
2130 | return st; | |
0f113f3e | 2131 | } |
c7820896 | 2132 | |
31a80694 | 2133 | static int test_badmod(void) |
0f113f3e | 2134 | { |
30bea14b RS |
2135 | BIGNUM *a = NULL, *b = NULL, *zero = NULL; |
2136 | BN_MONT_CTX *mont = NULL; | |
8d1ebff4 | 2137 | int st = 0; |
0f113f3e | 2138 | |
30bea14b RS |
2139 | if (!TEST_ptr(a = BN_new()) |
2140 | || !TEST_ptr(b = BN_new()) | |
2141 | || !TEST_ptr(zero = BN_new()) | |
2142 | || !TEST_ptr(mont = BN_MONT_CTX_new())) | |
0f113f3e | 2143 | goto err; |
8d1ebff4 | 2144 | BN_zero(zero); |
0f113f3e | 2145 | |
30bea14b | 2146 | if (!TEST_false(BN_div(a, b, BN_value_one(), zero, ctx))) |
8d1ebff4 | 2147 | goto err; |
8d1ebff4 | 2148 | ERR_clear_error(); |
0f113f3e | 2149 | |
30bea14b | 2150 | if (!TEST_false(BN_mod_mul(a, BN_value_one(), BN_value_one(), zero, ctx))) |
8d1ebff4 | 2151 | goto err; |
8d1ebff4 | 2152 | ERR_clear_error(); |
0f113f3e | 2153 | |
30bea14b | 2154 | if (!TEST_false(BN_mod_exp(a, BN_value_one(), BN_value_one(), zero, ctx))) |
8d1ebff4 | 2155 | goto err; |
8d1ebff4 | 2156 | ERR_clear_error(); |
0f113f3e | 2157 | |
30bea14b RS |
2158 | if (!TEST_false(BN_mod_exp_mont(a, BN_value_one(), BN_value_one(), |
2159 | zero, ctx, NULL))) | |
8d1ebff4 | 2160 | goto err; |
8d1ebff4 | 2161 | ERR_clear_error(); |
0f113f3e | 2162 | |
30bea14b | 2163 | if (!TEST_false(BN_mod_exp_mont_consttime(a, BN_value_one(), BN_value_one(), |
fe16ae5f | 2164 | zero, ctx, NULL))) |
8d1ebff4 | 2165 | goto err; |
8d1ebff4 | 2166 | ERR_clear_error(); |
0f113f3e | 2167 | |
30bea14b | 2168 | if (!TEST_false(BN_MONT_CTX_set(mont, zero, ctx))) |
8d1ebff4 | 2169 | goto err; |
8d1ebff4 | 2170 | ERR_clear_error(); |
0f113f3e | 2171 | |
8d1ebff4 | 2172 | /* Some operations also may not be used with an even modulus. */ |
30bea14b | 2173 | if (!TEST_true(BN_set_word(b, 16))) |
8d1ebff4 | 2174 | goto err; |
0f113f3e | 2175 | |
30bea14b | 2176 | if (!TEST_false(BN_MONT_CTX_set(mont, b, ctx))) |
8d1ebff4 | 2177 | goto err; |
8d1ebff4 | 2178 | ERR_clear_error(); |
0f113f3e | 2179 | |
30bea14b RS |
2180 | if (!TEST_false(BN_mod_exp_mont(a, BN_value_one(), BN_value_one(), |
2181 | b, ctx, NULL))) | |
8d1ebff4 | 2182 | goto err; |
8d1ebff4 RS |
2183 | ERR_clear_error(); |
2184 | ||
30bea14b | 2185 | if (!TEST_false(BN_mod_exp_mont_consttime(a, BN_value_one(), BN_value_one(), |
fe16ae5f | 2186 | b, ctx, NULL))) |
8d1ebff4 | 2187 | goto err; |
8d1ebff4 RS |
2188 | ERR_clear_error(); |
2189 | ||
2190 | st = 1; | |
fe16ae5f | 2191 | err: |
23a1d5e9 | 2192 | BN_free(a); |
8d1ebff4 RS |
2193 | BN_free(b); |
2194 | BN_free(zero); | |
2195 | BN_MONT_CTX_free(mont); | |
2196 | return st; | |
0f113f3e MC |
2197 | } |
2198 | ||
31a80694 | 2199 | static int test_expmodzero(void) |
0f113f3e | 2200 | { |
30bea14b | 2201 | BIGNUM *a = NULL, *r = NULL, *zero = NULL; |
8d1ebff4 | 2202 | int st = 0; |
0f113f3e | 2203 | |
30bea14b RS |
2204 | if (!TEST_ptr(zero = BN_new()) |
2205 | || !TEST_ptr(a = BN_new()) | |
2206 | || !TEST_ptr(r = BN_new())) | |
0f113f3e | 2207 | goto err; |
8d1ebff4 RS |
2208 | BN_zero(zero); |
2209 | ||
30bea14b | 2210 | if (!TEST_true(BN_mod_exp(r, a, zero, BN_value_one(), NULL)) |
dc352c19 | 2211 | || !TEST_BN_eq_zero(r) |
30bea14b RS |
2212 | || !TEST_true(BN_mod_exp_mont(r, a, zero, BN_value_one(), |
2213 | NULL, NULL)) | |
dc352c19 | 2214 | || !TEST_BN_eq_zero(r) |
30bea14b RS |
2215 | || !TEST_true(BN_mod_exp_mont_consttime(r, a, zero, |
2216 | BN_value_one(), | |
2217 | NULL, NULL)) | |
dc352c19 | 2218 | || !TEST_BN_eq_zero(r) |
30bea14b RS |
2219 | || !TEST_true(BN_mod_exp_mont_word(r, 42, zero, |
2220 | BN_value_one(), NULL, NULL)) | |
dc352c19 | 2221 | || !TEST_BN_eq_zero(r)) |
0f113f3e | 2222 | goto err; |
0f113f3e | 2223 | |
8d1ebff4 | 2224 | st = 1; |
fe16ae5f | 2225 | err: |
8d1ebff4 RS |
2226 | BN_free(zero); |
2227 | BN_free(a); | |
2228 | BN_free(r); | |
2229 | return st; | |
0f113f3e MC |
2230 | } |
2231 | ||
adf65243 MC |
2232 | static int test_expmodone(void) |
2233 | { | |
2234 | int ret = 0, i; | |
2235 | BIGNUM *r = BN_new(); | |
2236 | BIGNUM *a = BN_new(); | |
2237 | BIGNUM *p = BN_new(); | |
2238 | BIGNUM *m = BN_new(); | |
2239 | ||
2240 | if (!TEST_ptr(r) | |
2241 | || !TEST_ptr(a) | |
2242 | || !TEST_ptr(p) | |
2243 | || !TEST_ptr(p) | |
2244 | || !TEST_ptr(m) | |
2245 | || !TEST_true(BN_set_word(a, 1)) | |
2246 | || !TEST_true(BN_set_word(p, 0)) | |
2247 | || !TEST_true(BN_set_word(m, 1))) | |
2248 | goto err; | |
2249 | ||
2250 | /* Calculate r = 1 ^ 0 mod 1, and check the result is always 0 */ | |
2251 | for (i = 0; i < 2; i++) { | |
2252 | if (!TEST_true(BN_mod_exp(r, a, p, m, NULL)) | |
2253 | || !TEST_BN_eq_zero(r) | |
2254 | || !TEST_true(BN_mod_exp_mont(r, a, p, m, NULL, NULL)) | |
2255 | || !TEST_BN_eq_zero(r) | |
2256 | || !TEST_true(BN_mod_exp_mont_consttime(r, a, p, m, NULL, NULL)) | |
2257 | || !TEST_BN_eq_zero(r) | |
2258 | || !TEST_true(BN_mod_exp_mont_word(r, 1, p, m, NULL, NULL)) | |
2259 | || !TEST_BN_eq_zero(r) | |
2260 | || !TEST_true(BN_mod_exp_simple(r, a, p, m, NULL)) | |
2261 | || !TEST_BN_eq_zero(r) | |
2262 | || !TEST_true(BN_mod_exp_recp(r, a, p, m, NULL)) | |
2263 | || !TEST_BN_eq_zero(r)) | |
2264 | goto err; | |
2265 | /* Repeat for r = 1 ^ 0 mod -1 */ | |
2266 | if (i == 0) | |
2267 | BN_set_negative(m, 1); | |
2268 | } | |
2269 | ||
2270 | ret = 1; | |
fe16ae5f | 2271 | err: |
adf65243 MC |
2272 | BN_free(r); |
2273 | BN_free(a); | |
2274 | BN_free(p); | |
2275 | BN_free(m); | |
2276 | return ret; | |
2277 | } | |
2278 | ||
291f616c | 2279 | static int test_smallprime(int kBits) |
8ff70f33 | 2280 | { |
30bea14b | 2281 | BIGNUM *r; |
8d1ebff4 | 2282 | int st = 0; |
8ff70f33 | 2283 | |
291f616c BE |
2284 | if (!TEST_ptr(r = BN_new())) |
2285 | goto err; | |
2286 | ||
2287 | if (kBits <= 1) { | |
2288 | if (!TEST_false(BN_generate_prime_ex(r, kBits, 0, | |
2289 | NULL, NULL, NULL))) | |
2290 | goto err; | |
2291 | } else { | |
2292 | if (!TEST_true(BN_generate_prime_ex(r, kBits, 0, | |
2293 | NULL, NULL, NULL)) | |
2294 | || !TEST_int_eq(BN_num_bits(r), kBits)) | |
2295 | goto err; | |
2296 | } | |
2297 | ||
2298 | st = 1; | |
2299 | err: | |
2300 | BN_free(r); | |
2301 | return st; | |
2302 | } | |
2303 | ||
2304 | static int test_smallsafeprime(int kBits) | |
2305 | { | |
2306 | BIGNUM *r; | |
2307 | int st = 0; | |
2308 | ||
2309 | if (!TEST_ptr(r = BN_new())) | |
8d1ebff4 | 2310 | goto err; |
8ff70f33 | 2311 | |
291f616c BE |
2312 | if (kBits <= 5 && kBits != 3) { |
2313 | if (!TEST_false(BN_generate_prime_ex(r, kBits, 1, | |
2314 | NULL, NULL, NULL))) | |
2315 | goto err; | |
2316 | } else { | |
2317 | if (!TEST_true(BN_generate_prime_ex(r, kBits, 1, | |
2318 | NULL, NULL, NULL)) | |
2319 | || !TEST_int_eq(BN_num_bits(r), kBits)) | |
2320 | goto err; | |
2321 | } | |
2322 | ||
8d1ebff4 | 2323 | st = 1; |
fe16ae5f | 2324 | err: |
8d1ebff4 RS |
2325 | BN_free(r); |
2326 | return st; | |
2327 | } | |
8ff70f33 | 2328 | |
7d79d13a SL |
2329 | static int primes[] = { 2, 3, 5, 7, 17863 }; |
2330 | ||
2331 | static int test_is_prime(int i) | |
6e64c560 AL |
2332 | { |
2333 | int ret = 0; | |
30bea14b | 2334 | BIGNUM *r = NULL; |
7d79d13a | 2335 | int trial; |
6e64c560 | 2336 | |
7d79d13a | 2337 | if (!TEST_ptr(r = BN_new())) |
6e64c560 | 2338 | goto err; |
6e64c560 | 2339 | |
7d79d13a SL |
2340 | for (trial = 0; trial <= 1; ++trial) { |
2341 | if (!TEST_true(BN_set_word(r, primes[i])) | |
42619397 | 2342 | || !TEST_int_eq(BN_check_prime(r, ctx, NULL), |
7d79d13a SL |
2343 | 1)) |
2344 | goto err; | |
2345 | } | |
2346 | ||
6e64c560 | 2347 | ret = 1; |
fe16ae5f | 2348 | err: |
7d79d13a SL |
2349 | BN_free(r); |
2350 | return ret; | |
2351 | } | |
6e64c560 | 2352 | |
7d79d13a SL |
2353 | static int not_primes[] = { -1, 0, 1, 4 }; |
2354 | ||
2355 | static int test_not_prime(int i) | |
2356 | { | |
2357 | int ret = 0; | |
2358 | BIGNUM *r = NULL; | |
2359 | int trial; | |
2360 | ||
2361 | if (!TEST_ptr(r = BN_new())) | |
2362 | goto err; | |
2363 | ||
2364 | for (trial = 0; trial <= 1; ++trial) { | |
2365 | if (!TEST_true(BN_set_word(r, not_primes[i])) | |
42619397 | 2366 | || !TEST_false(BN_check_prime(r, ctx, NULL))) |
7d79d13a SL |
2367 | goto err; |
2368 | } | |
2369 | ||
2370 | ret = 1; | |
fe16ae5f | 2371 | err: |
6e64c560 AL |
2372 | BN_free(r); |
2373 | return ret; | |
2374 | } | |
2375 | ||
fe16ae5f NT |
2376 | static int test_ctx_set_ct_flag(BN_CTX *c) |
2377 | { | |
2378 | int st = 0; | |
2379 | size_t i; | |
2380 | BIGNUM *b[15]; | |
2381 | ||
2382 | BN_CTX_start(c); | |
2383 | for (i = 0; i < OSSL_NELEM(b); i++) { | |
2384 | if (!TEST_ptr(b[i] = BN_CTX_get(c))) | |
2385 | goto err; | |
2386 | if (i % 2 == 1) | |
2387 | BN_set_flags(b[i], BN_FLG_CONSTTIME); | |
2388 | } | |
2389 | ||
2390 | st = 1; | |
2391 | err: | |
2392 | BN_CTX_end(c); | |
2393 | return st; | |
2394 | } | |
2395 | ||
2396 | static int test_ctx_check_ct_flag(BN_CTX *c) | |
2397 | { | |
2398 | int st = 0; | |
2399 | size_t i; | |
2400 | BIGNUM *b[30]; | |
2401 | ||
2402 | BN_CTX_start(c); | |
2403 | for (i = 0; i < OSSL_NELEM(b); i++) { | |
2404 | if (!TEST_ptr(b[i] = BN_CTX_get(c))) | |
2405 | goto err; | |
2406 | if (!TEST_false(BN_get_flags(b[i], BN_FLG_CONSTTIME))) | |
2407 | goto err; | |
2408 | } | |
2409 | ||
2410 | st = 1; | |
2411 | err: | |
2412 | BN_CTX_end(c); | |
2413 | return st; | |
2414 | } | |
2415 | ||
2416 | static int test_ctx_consttime_flag(void) | |
2417 | { | |
2418 | /*- | |
2419 | * The constant-time flag should not "leak" among BN_CTX frames: | |
2420 | * | |
2421 | * - test_ctx_set_ct_flag() starts a frame in the given BN_CTX and | |
2422 | * sets the BN_FLG_CONSTTIME flag on some of the BIGNUMs obtained | |
2423 | * from the frame before ending it. | |
2424 | * - test_ctx_check_ct_flag() then starts a new frame and gets a | |
2425 | * number of BIGNUMs from it. In absence of leaks, none of the | |
2426 | * BIGNUMs in the new frame should have BN_FLG_CONSTTIME set. | |
2427 | * | |
2428 | * In actual BN_CTX usage inside libcrypto the leak could happen at | |
2429 | * any depth level in the BN_CTX stack, with varying results | |
2430 | * depending on the patterns of sibling trees of nested function | |
2431 | * calls sharing the same BN_CTX object, and the effect of | |
2432 | * unintended BN_FLG_CONSTTIME on the called BN_* functions. | |
2433 | * | |
2434 | * This simple unit test abstracts away this complexity and verifies | |
2435 | * that the leak does not happen between two sibling functions | |
2436 | * sharing the same BN_CTX object at the same level of nesting. | |
2437 | * | |
2438 | */ | |
2439 | BN_CTX *nctx = NULL; | |
2440 | BN_CTX *sctx = NULL; | |
2441 | size_t i = 0; | |
2442 | int st = 0; | |
2443 | ||
2444 | if (!TEST_ptr(nctx = BN_CTX_new()) | |
2445 | || !TEST_ptr(sctx = BN_CTX_secure_new())) | |
2446 | goto err; | |
2447 | ||
2448 | for (i = 0; i < 2; i++) { | |
2449 | BN_CTX *c = i == 0 ? nctx : sctx; | |
2450 | if (!TEST_true(test_ctx_set_ct_flag(c)) | |
2451 | || !TEST_true(test_ctx_check_ct_flag(c))) | |
2452 | goto err; | |
2453 | } | |
2454 | ||
2455 | st = 1; | |
2456 | err: | |
2457 | BN_CTX_free(nctx); | |
2458 | BN_CTX_free(sctx); | |
2459 | return st; | |
2460 | } | |
2461 | ||
b75d6310 CPG |
2462 | static int test_gcd_prime(void) |
2463 | { | |
2464 | BIGNUM *a = NULL, *b = NULL, *gcd = NULL; | |
2465 | int i, st = 0; | |
2466 | ||
2467 | if (!TEST_ptr(a = BN_new()) | |
2468 | || !TEST_ptr(b = BN_new()) | |
2469 | || !TEST_ptr(gcd = BN_new())) | |
2470 | goto err; | |
2471 | ||
2472 | if (!TEST_true(BN_generate_prime_ex(a, 1024, 0, NULL, NULL, NULL))) | |
2473 | goto err; | |
2474 | for (i = 0; i < NUM0; i++) { | |
2475 | if (!TEST_true(BN_generate_prime_ex(b, 1024, 0, | |
2476 | NULL, NULL, NULL)) | |
2477 | || !TEST_true(BN_gcd(gcd, a, b, ctx)) | |
2478 | || !TEST_true(BN_is_one(gcd))) | |
2479 | goto err; | |
2480 | } | |
2481 | ||
2482 | st = 1; | |
2483 | err: | |
2484 | BN_free(a); | |
2485 | BN_free(b); | |
2486 | BN_free(gcd); | |
2487 | return st; | |
2488 | } | |
2489 | ||
18d42d8d BE |
2490 | typedef struct mod_exp_test_st |
2491 | { | |
2492 | const char *base; | |
2493 | const char *exp; | |
2494 | const char *mod; | |
2495 | const char *res; | |
2496 | } MOD_EXP_TEST; | |
2497 | ||
2498 | static const MOD_EXP_TEST ModExpTests[] = { | |
2499 | /* original test vectors for rsaz_512_sqr bug, by OSS-Fuzz */ | |
2500 | { | |
2501 | "1166180238001879113042182292626169621106255558914000595999312084" | |
2502 | "4627946820899490684928760491249738643524880720584249698100907201" | |
2503 | "002086675047927600340800371", | |
2504 | "8000000000000000000000000000000000000000000000000000000000000000" | |
2505 | "0000000000000000000000000000000000000000000000000000000000000000" | |
2506 | "00000000", | |
2507 | "1340780792684523720980737645613191762604395855615117867483316354" | |
2508 | "3294276330515137663421134775482798690129946803802212663956180562" | |
2509 | "088664022929883876655300863", | |
2510 | "8243904058268085430037326628480645845409758077568738532059032482" | |
2511 | "8294114415890603594730158120426756266457928475330450251339773498" | |
2512 | "26758407619521544102068438" | |
2513 | }, | |
2514 | { | |
2515 | "4974270041410803822078866696159586946995877618987010219312844726" | |
2516 | "0284386121835740784990869050050504348861513337232530490826340663" | |
2517 | "197278031692737429054", | |
2518 | "4974270041410803822078866696159586946995877428188754995041148539" | |
2519 | "1663243362592271353668158565195557417149981094324650322556843202" | |
2520 | "946445882670777892608", | |
2521 | "1340780716511420227215592830971452482815377482627251725537099028" | |
2522 | "4429769497230131760206012644403029349547320953206103351725462999" | |
2523 | "947509743623340557059752191", | |
2524 | "5296244594780707015616522701706118082963369547253192207884519362" | |
2525 | "1767869984947542695665420219028522815539559194793619684334900442" | |
2526 | "49304558011362360473525933" | |
2527 | }, | |
2528 | /* test vectors for rsaz_512_srq bug, with rcx/rbx=1 */ | |
2529 | { /* between first and second iteration */ | |
2530 | "5148719036160389201525610950887605325980251964889646556085286545" | |
2531 | "3931548809178823413169359635978762036512397113080988070677858033" | |
2532 | "36463909753993540214027190", | |
2533 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2534 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2535 | "05973284973216824503042158", | |
2536 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2537 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2538 | "05973284973216824503042159", | |
2539 | "1" | |
2540 | }, | |
2541 | { /* between second and third iteration */ | |
2542 | "8908340854353752577419678771330460827942371434853054158622636544" | |
2543 | "8151360109722890949471912566649465436296659601091730745087014189" | |
2544 | "2672764191218875181826063", | |
2545 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2546 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2547 | "05973284973216824503042158", | |
2548 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2549 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2550 | "05973284973216824503042159", | |
2551 | "1" | |
2552 | }, | |
2553 | { /* between third and fourth iteration */ | |
2554 | "3427446396505596330634350984901719674479522569002785244080234738" | |
2555 | "4288743635435746136297299366444548736533053717416735379073185344" | |
2556 | "26985272974404612945608761", | |
2557 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2558 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2559 | "05973284973216824503042158", | |
2560 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2561 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2562 | "05973284973216824503042159", | |
2563 | "1" | |
2564 | }, | |
2565 | { /* between fourth and fifth iteration */ | |
2566 | "3472743044917564564078857826111874560045331237315597383869652985" | |
2567 | "6919870028890895988478351133601517365908445058405433832718206902" | |
2568 | "4088133164805266956353542", | |
2569 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2570 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2571 | "05973284973216824503042158", | |
2572 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2573 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2574 | "05973284973216824503042159", | |
2575 | "1" | |
2576 | }, | |
2577 | { /* between fifth and sixth iteration */ | |
2578 | "3608632990153469264412378349742339216742409743898601587274768025" | |
2579 | "0110772032985643555192767717344946174122842255204082586753499651" | |
2580 | "14483434992887431333675068", | |
2581 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2582 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2583 | "05973284973216824503042158", | |
2584 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2585 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2586 | "05973284973216824503042159", | |
2587 | "1" | |
2588 | }, | |
2589 | { /* between sixth and seventh iteration */ | |
2590 | "8455374370234070242910508226941981520235709767260723212165264877" | |
2591 | "8689064388017521524568434328264431772644802567028663962962025746" | |
2592 | "9283458217850119569539086", | |
2593 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2594 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2595 | "05973284973216824503042158", | |
2596 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2597 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2598 | "05973284973216824503042159", | |
2599 | "1" | |
2600 | }, | |
2601 | { /* between seventh and eighth iteration */ | |
2602 | "5155371529688532178421209781159131443543419764974688878527112131" | |
2603 | "7446518205609427412336183157918981038066636807317733319323257603" | |
2604 | "04416292040754017461076359", | |
2605 | "1005585594745694782468051874865438459560952436544429503329267108" | |
2606 | "2791323022555160232601405723625177570767523893639864538140315412" | |
2607 | "108959927459825236754563832", | |
2608 | "1005585594745694782468051874865438459560952436544429503329267108" | |
2609 | "2791323022555160232601405723625177570767523893639864538140315412" | |
2610 | "108959927459825236754563833", | |
2611 | "1" | |
2612 | }, | |
2613 | /* test vectors for rsaz_512_srq bug, with rcx/rbx=2 */ | |
2614 | { /* between first and second iteration */ | |
2615 | "3155666506033786929967309937640790361084670559125912405342594979" | |
2616 | "4345142818528956285490897841406338022378565972533508820577760065" | |
2617 | "58494345853302083699912572", | |
2618 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2619 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2620 | "05973284973216824503042158", | |
2621 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2622 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2623 | "05973284973216824503042159", | |
2624 | "1" | |
2625 | }, | |
2626 | { /* between second and third iteration */ | |
2627 | "3789819583801342198190405714582958759005991915505282362397087750" | |
2628 | "4213544724644823098843135685133927198668818185338794377239590049" | |
2629 | "41019388529192775771488319", | |
2630 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2631 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2632 | "05973284973216824503042158", | |
2633 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2634 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2635 | "05973284973216824503042159", | |
2636 | "1" | |
2637 | }, | |
2638 | { /* between third and forth iteration */ | |
2639 | "4695752552040706867080542538786056470322165281761525158189220280" | |
2640 | "4025547447667484759200742764246905647644662050122968912279199065" | |
2641 | "48065034299166336940507214", | |
2642 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2643 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2644 | "05973284973216824503042158", | |
2645 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2646 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2647 | "05973284973216824503042159", | |
2648 | "1" | |
2649 | }, | |
2650 | { /* between forth and fifth iteration */ | |
2651 | "2159140240970485794188159431017382878636879856244045329971239574" | |
2652 | "8919691133560661162828034323196457386059819832804593989740268964" | |
2653 | "74502911811812651475927076", | |
2654 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2655 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2656 | "05973284973216824503042158", | |
2657 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2658 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2659 | "05973284973216824503042159", | |
2660 | "1" | |
2661 | }, | |
2662 | { /* between fifth and sixth iteration */ | |
2663 | "5239312332984325668414624633307915097111691815000872662334695514" | |
2664 | "5436533521392362443557163429336808208137221322444780490437871903" | |
2665 | "99972784701334569424519255", | |
2666 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2667 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2668 | "05973284973216824503042158", | |
2669 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2670 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2671 | "05973284973216824503042159", | |
2672 | "1" | |
2673 | }, | |
2674 | { /* between sixth and seventh iteration */ | |
2675 | "1977953647322612860406858017869125467496941904523063466791308891" | |
2676 | "1172796739058531929470539758361774569875505293428856181093904091" | |
2677 | "33788264851714311303725089", | |
2678 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2679 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2680 | "05973284973216824503042158", | |
2681 | "6703903964971298549787012499102923063739682910296196688861780721" | |
2682 | "8608820150367734884009371490834517138450159290932430254268769414" | |
2683 | "05973284973216824503042159", | |
2684 | "1" | |
2685 | }, | |
2686 | { /* between seventh and eighth iteration */ | |
2687 | "6456987954117763835533395796948878140715006860263624787492985786" | |
2688 | "8514630216966738305923915688821526449499763719943997120302368211" | |
2689 | "04813318117996225041943964", | |
2690 | "1340780792994259709957402499820584612747936582059239337772356144" | |
2691 | "3721764030073546976801874298166903427690031858186486050853753882" | |
2692 | "811946551499689575296532556", | |
2693 | "1340780792994259709957402499820584612747936582059239337772356144" | |
2694 | "3721764030073546976801874298166903427690031858186486050853753882" | |
2695 | "811946551499689575296532557", | |
2696 | "1" | |
2697 | } | |
2698 | }; | |
2699 | ||
2700 | static int test_mod_exp(int i) | |
2701 | { | |
2702 | const MOD_EXP_TEST *test = &ModExpTests[i]; | |
2703 | int res = 0; | |
2704 | BIGNUM* result = NULL; | |
2705 | BIGNUM *base = NULL, *exponent = NULL, *modulo = NULL; | |
2706 | char *s = NULL; | |
2707 | ||
2708 | if (!TEST_ptr(result = BN_new()) | |
2709 | || !TEST_true(BN_dec2bn(&base, test->base)) | |
2710 | || !TEST_true(BN_dec2bn(&exponent, test->exp)) | |
2711 | || !TEST_true(BN_dec2bn(&modulo, test->mod))) | |
2712 | goto err; | |
2713 | ||
2714 | if (!TEST_int_eq(BN_mod_exp(result, base, exponent, modulo, ctx), 1)) | |
2715 | goto err; | |
2716 | ||
2717 | if (!TEST_ptr(s = BN_bn2dec(result))) | |
2718 | goto err; | |
2719 | ||
2720 | if (!TEST_mem_eq(s, strlen(s), test->res, strlen(test->res))) | |
2721 | goto err; | |
2722 | ||
2723 | res = 1; | |
2724 | ||
2725 | err: | |
2726 | OPENSSL_free(s); | |
2727 | BN_free(result); | |
2728 | BN_free(base); | |
2729 | BN_free(exponent); | |
2730 | BN_free(modulo); | |
2731 | return res; | |
2732 | } | |
2733 | ||
2734 | static int test_mod_exp_consttime(int i) | |
2735 | { | |
2736 | const MOD_EXP_TEST *test = &ModExpTests[i]; | |
2737 | int res = 0; | |
2738 | BIGNUM* result = NULL; | |
2739 | BIGNUM *base = NULL, *exponent = NULL, *modulo = NULL; | |
2740 | char *s = NULL; | |
2741 | ||
2742 | if (!TEST_ptr(result = BN_new()) | |
2743 | || !TEST_true(BN_dec2bn(&base, test->base)) | |
2744 | || !TEST_true(BN_dec2bn(&exponent, test->exp)) | |
2745 | || !TEST_true(BN_dec2bn(&modulo, test->mod))) | |
2746 | goto err; | |
2747 | ||
2748 | BN_set_flags(base, BN_FLG_CONSTTIME); | |
2749 | BN_set_flags(exponent, BN_FLG_CONSTTIME); | |
2750 | BN_set_flags(modulo, BN_FLG_CONSTTIME); | |
2751 | ||
2752 | if (!TEST_int_eq(BN_mod_exp(result, base, exponent, modulo, ctx), 1)) | |
2753 | goto err; | |
2754 | ||
2755 | if (!TEST_ptr(s = BN_bn2dec(result))) | |
2756 | goto err; | |
2757 | ||
2758 | if (!TEST_mem_eq(s, strlen(s), test->res, strlen(test->res))) | |
2759 | goto err; | |
2760 | ||
2761 | res = 1; | |
2762 | ||
2763 | err: | |
2764 | OPENSSL_free(s); | |
2765 | BN_free(result); | |
2766 | BN_free(base); | |
2767 | BN_free(exponent); | |
2768 | BN_free(modulo); | |
2769 | return res; | |
2770 | } | |
2771 | ||
8d1ebff4 | 2772 | static int file_test_run(STANZA *s) |
0f113f3e | 2773 | { |
8d1ebff4 RS |
2774 | static const FILETEST filetests[] = { |
2775 | {"Sum", file_sum}, | |
2776 | {"LShift1", file_lshift1}, | |
2777 | {"LShift", file_lshift}, | |
2778 | {"RShift", file_rshift}, | |
2779 | {"Square", file_square}, | |
2780 | {"Product", file_product}, | |
2781 | {"Quotient", file_quotient}, | |
2782 | {"ModMul", file_modmul}, | |
2783 | {"ModExp", file_modexp}, | |
2784 | {"Exp", file_exp}, | |
2785 | {"ModSqrt", file_modsqrt}, | |
b75d6310 | 2786 | {"GCD", file_gcd}, |
8d1ebff4 RS |
2787 | }; |
2788 | int numtests = OSSL_NELEM(filetests); | |
2789 | const FILETEST *tp = filetests; | |
0f113f3e | 2790 | |
8d1ebff4 | 2791 | for ( ; --numtests >= 0; tp++) { |
30bea14b RS |
2792 | if (findattr(s, tp->name) != NULL) { |
2793 | if (!tp->func(s)) { | |
ae269dd8 RS |
2794 | TEST_info("%s:%d: Failed %s test", |
2795 | s->test_file, s->start, tp->name); | |
30bea14b RS |
2796 | return 0; |
2797 | } | |
2798 | return 1; | |
2799 | } | |
0f113f3e | 2800 | } |
ae269dd8 | 2801 | TEST_info("%s:%d: Unknown test", s->test_file, s->start); |
8d1ebff4 | 2802 | return 0; |
0f113f3e | 2803 | } |
d02b48c6 | 2804 | |
e1cfd184 | 2805 | static int run_file_tests(int i) |
0f113f3e | 2806 | { |
ae269dd8 | 2807 | STANZA *s = NULL; |
ad887416 | 2808 | char *testfile = test_get_argument(i); |
ae269dd8 | 2809 | int c; |
0f113f3e | 2810 | |
ae269dd8 | 2811 | if (!TEST_ptr(s = OPENSSL_zalloc(sizeof(*s)))) |
e1cfd184 | 2812 | return 0; |
ad887416 | 2813 | if (!test_start_file(s, testfile)) { |
ae269dd8 RS |
2814 | OPENSSL_free(s); |
2815 | return 0; | |
2816 | } | |
e1cfd184 | 2817 | |
8d1ebff4 | 2818 | /* Read test file. */ |
ae269dd8 RS |
2819 | while (!BIO_eof(s->fp) && test_readstanza(s)) { |
2820 | if (s->numpairs == 0) | |
8d1ebff4 | 2821 | continue; |
ae269dd8 RS |
2822 | if (!file_test_run(s)) |
2823 | s->errors++; | |
2824 | s->numtests++; | |
2825 | test_clearstanza(s); | |
0f113f3e | 2826 | } |
ae269dd8 RS |
2827 | test_end_file(s); |
2828 | c = s->errors; | |
2829 | OPENSSL_free(s); | |
8d1ebff4 | 2830 | |
ae269dd8 | 2831 | return c == 0; |
0f113f3e | 2832 | } |
d02b48c6 | 2833 | |
5d2f3e4a P |
2834 | typedef enum OPTION_choice { |
2835 | OPT_ERR = -1, | |
2836 | OPT_EOF = 0, | |
2837 | OPT_STOCHASTIC_TESTS, | |
2838 | OPT_TEST_ENUM | |
2839 | } OPTION_CHOICE; | |
2840 | ||
a43ce58f SL |
2841 | const OPTIONS *test_get_options(void) |
2842 | { | |
a43ce58f SL |
2843 | static const OPTIONS test_options[] = { |
2844 | OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("[file...]\n"), | |
5d2f3e4a | 2845 | { "stochastic", OPT_STOCHASTIC_TESTS, '-', "Run stochastic tests" }, |
a43ce58f SL |
2846 | { OPT_HELP_STR, 1, '-', |
2847 | "file\tFile to run tests on. Normal tests are not run\n" }, | |
2848 | { NULL } | |
2849 | }; | |
2850 | return test_options; | |
2851 | } | |
e1cfd184 | 2852 | |
ad887416 | 2853 | int setup_tests(void) |
0f113f3e | 2854 | { |
5d2f3e4a P |
2855 | OPTION_CHOICE o; |
2856 | int n, stochastic = 0; | |
2857 | ||
2858 | while ((o = opt_next()) != OPT_EOF) { | |
2859 | switch (o) { | |
2860 | case OPT_STOCHASTIC_TESTS: | |
2861 | stochastic = 1; | |
2862 | break; | |
2863 | case OPT_TEST_CASES: | |
2864 | break; | |
2865 | default: | |
2866 | case OPT_ERR: | |
dd6b2706 | 2867 | return 0; |
5d2f3e4a P |
2868 | } |
2869 | } | |
2870 | n = test_get_argument_count(); | |
8d1ebff4 | 2871 | |
e1cfd184 | 2872 | if (!TEST_ptr(ctx = BN_CTX_new())) |
ad887416 | 2873 | return 0; |
e1cfd184 | 2874 | |
ad887416 | 2875 | if (n == 0) { |
e1cfd184 RS |
2876 | ADD_TEST(test_sub); |
2877 | ADD_TEST(test_div_recip); | |
2878 | ADD_TEST(test_mod); | |
2879 | ADD_TEST(test_modexp_mont5); | |
2880 | ADD_TEST(test_kronecker); | |
2881 | ADD_TEST(test_rand); | |
2882 | ADD_TEST(test_bn2padded); | |
2883 | ADD_TEST(test_dec2bn); | |
2884 | ADD_TEST(test_hex2bn); | |
2885 | ADD_TEST(test_asc2bn); | |
2886 | ADD_ALL_TESTS(test_mpi, (int)OSSL_NELEM(kMPITests)); | |
2887 | ADD_TEST(test_negzero); | |
2888 | ADD_TEST(test_badmod); | |
2889 | ADD_TEST(test_expmodzero); | |
adf65243 | 2890 | ADD_TEST(test_expmodone); |
291f616c BE |
2891 | ADD_ALL_TESTS(test_smallprime, 16); |
2892 | ADD_ALL_TESTS(test_smallsafeprime, 16); | |
9e5b50b5 | 2893 | ADD_TEST(test_swap); |
fe16ae5f | 2894 | ADD_TEST(test_ctx_consttime_flag); |
8d1ebff4 | 2895 | #ifndef OPENSSL_NO_EC2M |
e1cfd184 RS |
2896 | ADD_TEST(test_gf2m_add); |
2897 | ADD_TEST(test_gf2m_mod); | |
2898 | ADD_TEST(test_gf2m_mul); | |
2899 | ADD_TEST(test_gf2m_sqr); | |
2900 | ADD_TEST(test_gf2m_modinv); | |
2901 | ADD_TEST(test_gf2m_moddiv); | |
2902 | ADD_TEST(test_gf2m_modexp); | |
2903 | ADD_TEST(test_gf2m_modsqrt); | |
2904 | ADD_TEST(test_gf2m_modsolvequad); | |
8d1ebff4 | 2905 | #endif |
7d79d13a SL |
2906 | ADD_ALL_TESTS(test_is_prime, (int)OSSL_NELEM(primes)); |
2907 | ADD_ALL_TESTS(test_not_prime, (int)OSSL_NELEM(not_primes)); | |
b75d6310 | 2908 | ADD_TEST(test_gcd_prime); |
18d42d8d BE |
2909 | ADD_ALL_TESTS(test_mod_exp, (int)OSSL_NELEM(ModExpTests)); |
2910 | ADD_ALL_TESTS(test_mod_exp_consttime, (int)OSSL_NELEM(ModExpTests)); | |
5d2f3e4a P |
2911 | if (stochastic) |
2912 | ADD_TEST(test_rand_range); | |
e1cfd184 | 2913 | } else { |
ad887416 | 2914 | ADD_ALL_TESTS(run_file_tests, n); |
e1cfd184 | 2915 | } |
ad887416 P |
2916 | return 1; |
2917 | } | |
8d1ebff4 | 2918 | |
ad887416 P |
2919 | void cleanup_tests(void) |
2920 | { | |
8d1ebff4 | 2921 | BN_CTX_free(ctx); |
0f113f3e | 2922 | } |