diff options
author | tb <> | 2022-12-02 17:33:38 +0000 |
---|---|---|
committer | tb <> | 2022-12-02 17:33:38 +0000 |
commit | 1cb6f2d70f545616fc841dd142ecacb8a1552432 (patch) | |
tree | a2bd6c766ad880828089a263ca315875c5d70a85 /src/regress/lib | |
parent | 93026bb74a9f942ea7b87dd3316996c7492a954f (diff) | |
download | openbsd-1cb6f2d70f545616fc841dd142ecacb8a1552432.tar.gz openbsd-1cb6f2d70f545616fc841dd142ecacb8a1552432.tar.bz2 openbsd-1cb6f2d70f545616fc841dd142ecacb8a1552432.zip |
Rewrite the tests that various modular exponentiation functions
compute a^0 = 0 (mod 1) for all a from scratch.
Diffstat (limited to 'src/regress/lib')
-rw-r--r-- | src/regress/lib/libcrypto/bn/bn_mod_exp.c | 150 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/bn/bn_mod_exp_zero.c | 187 |
2 files changed, 189 insertions, 148 deletions
diff --git a/src/regress/lib/libcrypto/bn/bn_mod_exp.c b/src/regress/lib/libcrypto/bn/bn_mod_exp.c index 337cbd1373..dc0fe27870 100644 --- a/src/regress/lib/libcrypto/bn/bn_mod_exp.c +++ b/src/regress/lib/libcrypto/bn/bn_mod_exp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_mod_exp.c,v 1.1 2022/12/01 21:21:51 tb Exp $ */ | 1 | /* $OpenBSD: bn_mod_exp.c,v 1.2 2022/12/02 17:33:38 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -64,153 +64,10 @@ | |||
64 | #include <openssl/bn.h> | 64 | #include <openssl/bn.h> |
65 | #include <openssl/err.h> | 65 | #include <openssl/err.h> |
66 | 66 | ||
67 | int BN_mod_exp_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | 67 | #include "bn_local.h" |
68 | const BIGNUM *m, BN_CTX *ctx); | ||
69 | int BN_mod_exp_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | ||
70 | const BIGNUM *m, BN_CTX *ctx); | ||
71 | int BN_mod_exp_mont_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | ||
72 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
73 | int BN_mod_exp_mont_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | ||
74 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
75 | 68 | ||
76 | #define NUM_BITS (BN_BITS*2) | 69 | #define NUM_BITS (BN_BITS*2) |
77 | 70 | ||
78 | /* | ||
79 | * Test that r == 0 in test_exp_mod_zero(). Returns one on success, | ||
80 | * returns zero and prints debug output otherwise. | ||
81 | */ | ||
82 | static int | ||
83 | a_is_zero_mod_one(const char *method, const BIGNUM *r, const BIGNUM *a) | ||
84 | { | ||
85 | if (!BN_is_zero(r)) { | ||
86 | fprintf(stderr, "%s failed:\n", method); | ||
87 | fprintf(stderr, "a ** 0 mod 1 = r (should be 0)\n"); | ||
88 | fprintf(stderr, "a = "); | ||
89 | BN_print_fp(stderr, a); | ||
90 | fprintf(stderr, "\nr = "); | ||
91 | BN_print_fp(stderr, r); | ||
92 | fprintf(stderr, "\n"); | ||
93 | return 0; | ||
94 | } | ||
95 | return 1; | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success. | ||
100 | */ | ||
101 | static int | ||
102 | test_exp_mod_zero(void) | ||
103 | { | ||
104 | BIGNUM *a = NULL, *p = NULL, *m = NULL, *r = NULL; | ||
105 | BN_ULONG one_word = 1; | ||
106 | BN_CTX *ctx; | ||
107 | int ret = 1, failed = 0; | ||
108 | |||
109 | if ((ctx = BN_CTX_new()) == NULL) | ||
110 | goto err; | ||
111 | if ((m = BN_new()) == NULL) | ||
112 | goto err; | ||
113 | if (!BN_one(m)) | ||
114 | goto err; | ||
115 | |||
116 | if ((a = BN_new()) == NULL) | ||
117 | goto err; | ||
118 | if (!BN_one(a)) | ||
119 | goto err; | ||
120 | |||
121 | if ((p = BN_new()) == NULL) | ||
122 | goto err; | ||
123 | BN_zero(p); | ||
124 | |||
125 | if ((r = BN_new()) == NULL) | ||
126 | goto err; | ||
127 | |||
128 | if (!BN_rand(a, 1024, 0, 0)) | ||
129 | goto err; | ||
130 | |||
131 | if (!BN_mod_exp(r, a, p, m, ctx)) | ||
132 | goto err; | ||
133 | |||
134 | if (!a_is_zero_mod_one("BN_mod_exp", r, a)) | ||
135 | failed = 1; | ||
136 | |||
137 | if (!BN_mod_exp_ct(r, a, p, m, ctx)) | ||
138 | goto err; | ||
139 | |||
140 | if (!a_is_zero_mod_one("BN_mod_exp_ct", r, a)) | ||
141 | failed = 1; | ||
142 | |||
143 | if (!BN_mod_exp_nonct(r, a, p, m, ctx)) | ||
144 | goto err; | ||
145 | |||
146 | if (!a_is_zero_mod_one("BN_mod_exp_nonct", r, a)) | ||
147 | failed = 1; | ||
148 | |||
149 | if (!BN_mod_exp_recp(r, a, p, m, ctx)) | ||
150 | goto err; | ||
151 | |||
152 | if (!a_is_zero_mod_one("BN_mod_exp_recp", r, a)) | ||
153 | failed = 1; | ||
154 | |||
155 | if (!BN_mod_exp_simple(r, a, p, m, ctx)) | ||
156 | goto err; | ||
157 | |||
158 | if (!a_is_zero_mod_one("BN_mod_exp_simple", r, a)) | ||
159 | failed = 1; | ||
160 | |||
161 | if (!BN_mod_exp_mont(r, a, p, m, ctx, NULL)) | ||
162 | goto err; | ||
163 | |||
164 | if (!a_is_zero_mod_one("BN_mod_exp_mont", r, a)) | ||
165 | failed = 1; | ||
166 | |||
167 | if (!BN_mod_exp_mont_ct(r, a, p, m, ctx, NULL)) | ||
168 | goto err; | ||
169 | |||
170 | if (!a_is_zero_mod_one("BN_mod_exp_mont_ct", r, a)) | ||
171 | failed = 1; | ||
172 | |||
173 | if (!BN_mod_exp_mont_nonct(r, a, p, m, ctx, NULL)) | ||
174 | goto err; | ||
175 | |||
176 | if (!a_is_zero_mod_one("BN_mod_exp_mont_nonct", r, a)) | ||
177 | failed = 1; | ||
178 | |||
179 | if (!BN_mod_exp_mont_consttime(r, a, p, m, ctx, NULL)) { | ||
180 | goto err; | ||
181 | } | ||
182 | |||
183 | if (!a_is_zero_mod_one("BN_mod_exp_mont_consttime", r, a)) | ||
184 | failed = 1; | ||
185 | |||
186 | /* | ||
187 | * A different codepath exists for single word multiplication | ||
188 | * in non-constant-time only. | ||
189 | */ | ||
190 | if (!BN_mod_exp_mont_word(r, one_word, p, m, ctx, NULL)) | ||
191 | goto err; | ||
192 | |||
193 | if (!BN_is_zero(r)) { | ||
194 | fprintf(stderr, "BN_mod_exp_mont_word failed:\n"); | ||
195 | fprintf(stderr, "1 ** 0 mod 1 = r (should be 0)\n"); | ||
196 | fprintf(stderr, "r = "); | ||
197 | BN_print_fp(stderr, r); | ||
198 | fprintf(stderr, "\n"); | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | ret = failed; | ||
203 | |||
204 | err: | ||
205 | BN_free(r); | ||
206 | BN_free(a); | ||
207 | BN_free(p); | ||
208 | BN_free(m); | ||
209 | BN_CTX_free(ctx); | ||
210 | |||
211 | return ret; | ||
212 | } | ||
213 | |||
214 | int | 71 | int |
215 | main(int argc, char *argv[]) | 72 | main(int argc, char *argv[]) |
216 | { | 73 | { |
@@ -346,9 +203,6 @@ main(int argc, char *argv[]) | |||
346 | CRYPTO_mem_leaks(out); | 203 | CRYPTO_mem_leaks(out); |
347 | BIO_free(out); | 204 | BIO_free(out); |
348 | 205 | ||
349 | if (test_exp_mod_zero() != 0) | ||
350 | goto err; | ||
351 | |||
352 | return (0); | 206 | return (0); |
353 | 207 | ||
354 | err: | 208 | err: |
diff --git a/src/regress/lib/libcrypto/bn/bn_mod_exp_zero.c b/src/regress/lib/libcrypto/bn/bn_mod_exp_zero.c new file mode 100644 index 0000000000..0e1e21d141 --- /dev/null +++ b/src/regress/lib/libcrypto/bn/bn_mod_exp_zero.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* $OpenBSD: bn_mod_exp_zero.c,v 1.1 2022/12/02 17:33:38 tb Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * Copyright (c) 2022 Theo Buehler <tb@openbsd.org> | ||
5 | * | ||
6 | * Permission to use, copy, modify, and distribute this software for any | ||
7 | * purpose with or without fee is hereby granted, provided that the above | ||
8 | * copyright notice and this permission notice appear in all copies. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include <stdio.h> | ||
20 | #include <err.h> | ||
21 | |||
22 | #include <openssl/bn.h> | ||
23 | #include <openssl/err.h> | ||
24 | |||
25 | #include "bn_local.h" | ||
26 | |||
27 | #define INIT_MOD_EXP_FN(f) { .name = #f, .mod_exp_fn = (f), } | ||
28 | #define INIT_MOD_EXP_MONT_FN(f) { .name = #f, .mod_exp_mont_fn = (f), } | ||
29 | |||
30 | static const struct mod_exp_zero_test { | ||
31 | const char *name; | ||
32 | int (*mod_exp_fn)(BIGNUM *,const BIGNUM *, const BIGNUM *, | ||
33 | const BIGNUM *, BN_CTX *); | ||
34 | int (*mod_exp_mont_fn)(BIGNUM *,const BIGNUM *, const BIGNUM *, | ||
35 | const BIGNUM *, BN_CTX *, BN_MONT_CTX *); | ||
36 | } mod_exp_zero_test_data[] = { | ||
37 | INIT_MOD_EXP_FN(BN_mod_exp), | ||
38 | INIT_MOD_EXP_FN(BN_mod_exp_ct), | ||
39 | INIT_MOD_EXP_FN(BN_mod_exp_nonct), | ||
40 | INIT_MOD_EXP_FN(BN_mod_exp_recp), | ||
41 | INIT_MOD_EXP_FN(BN_mod_exp_simple), | ||
42 | INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont), | ||
43 | INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont_ct), | ||
44 | INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont_consttime), | ||
45 | INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont_nonct), | ||
46 | }; | ||
47 | |||
48 | #define N_MOD_EXP_ZERO_TESTS \ | ||
49 | (sizeof(mod_exp_zero_test_data) / sizeof(mod_exp_zero_test_data[0])) | ||
50 | |||
51 | static void | ||
52 | print_failure(const BIGNUM *result, const BIGNUM *a, const char *name) | ||
53 | { | ||
54 | fprintf(stderr, "%s test failed for a = ", name); | ||
55 | BN_print_fp(stderr, a); | ||
56 | fprintf(stderr, "\nwant 0, got "); | ||
57 | BN_print_fp(stderr, result); | ||
58 | fprintf(stderr, "\n"); | ||
59 | } | ||
60 | |||
61 | static int | ||
62 | bn_mod_exp_zero_test(const struct mod_exp_zero_test *test, BN_CTX *ctx, | ||
63 | int use_random) | ||
64 | { | ||
65 | const BIGNUM *one; | ||
66 | BIGNUM *a, *p, *result; | ||
67 | int failed = 1; | ||
68 | |||
69 | BN_CTX_start(ctx); | ||
70 | |||
71 | if ((a = BN_CTX_get(ctx)) == NULL) | ||
72 | errx(1, "BN_CTX_get"); | ||
73 | if ((p = BN_CTX_get(ctx)) == NULL) | ||
74 | errx(1, "BN_CTX_get"); | ||
75 | if ((result = BN_CTX_get(ctx)) == NULL) | ||
76 | errx(1, "BN_CTX_get"); | ||
77 | |||
78 | one = BN_value_one(); | ||
79 | BN_zero(a); | ||
80 | BN_zero(p); | ||
81 | |||
82 | if (use_random) { | ||
83 | if (!BN_rand(a, 1024, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) | ||
84 | errx(1, "BN_rand"); | ||
85 | } | ||
86 | |||
87 | if (test->mod_exp_fn != NULL) { | ||
88 | if (!test->mod_exp_fn(result, a, p, one, ctx)) { | ||
89 | fprintf(stderr, "%s failed\n", test->name); | ||
90 | ERR_print_errors_fp(stderr); | ||
91 | goto err; | ||
92 | } | ||
93 | } else { | ||
94 | if (!test->mod_exp_mont_fn(result, a, p, one, ctx, NULL)) { | ||
95 | fprintf(stderr, "%s failed\n", test->name); | ||
96 | ERR_print_errors_fp(stderr); | ||
97 | goto err; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | if (!BN_is_zero(result)) { | ||
102 | print_failure(result, a, test->name); | ||
103 | goto err; | ||
104 | } | ||
105 | |||
106 | failed = 0; | ||
107 | |||
108 | err: | ||
109 | BN_CTX_end(ctx); | ||
110 | |||
111 | return failed; | ||
112 | } | ||
113 | |||
114 | static int | ||
115 | bn_mod_exp_zero_word_test(BN_CTX *ctx) | ||
116 | { | ||
117 | const char *name = "BN_mod_exp_mont_word"; | ||
118 | const BIGNUM *one; | ||
119 | BIGNUM *p, *result; | ||
120 | int failed = 1; | ||
121 | |||
122 | BN_CTX_start(ctx); | ||
123 | |||
124 | if ((p = BN_CTX_get(ctx)) == NULL) | ||
125 | errx(1, "BN_CTX_get"); | ||
126 | if ((result = BN_CTX_get(ctx)) == NULL) | ||
127 | errx(1, "BN_CTX_get"); | ||
128 | |||
129 | one = BN_value_one(); | ||
130 | BN_zero(p); | ||
131 | |||
132 | if (!BN_mod_exp_mont_word(result, 1, p, one, ctx, NULL)) { | ||
133 | fprintf(stderr, "%s failed\n", name); | ||
134 | ERR_print_errors_fp(stderr); | ||
135 | goto err; | ||
136 | } | ||
137 | |||
138 | if (!BN_is_zero(result)) { | ||
139 | print_failure(result, one, name); | ||
140 | goto err; | ||
141 | } | ||
142 | |||
143 | failed = 0; | ||
144 | |||
145 | err: | ||
146 | BN_CTX_end(ctx); | ||
147 | |||
148 | return failed; | ||
149 | } | ||
150 | |||
151 | static int | ||
152 | run_bn_mod_exp_zero_tests(void) | ||
153 | { | ||
154 | BN_CTX *ctx; | ||
155 | size_t i; | ||
156 | int use_random; | ||
157 | int failed = 0; | ||
158 | |||
159 | if ((ctx = BN_CTX_new()) == NULL) | ||
160 | errx(1, "BN_CTX_new"); | ||
161 | |||
162 | use_random = 1; | ||
163 | for (i = 0; i < N_MOD_EXP_ZERO_TESTS; i++) | ||
164 | failed |= bn_mod_exp_zero_test(&mod_exp_zero_test_data[i], ctx, | ||
165 | use_random); | ||
166 | |||
167 | use_random = 0; | ||
168 | for (i = 0; i < N_MOD_EXP_ZERO_TESTS; i++) | ||
169 | failed |= bn_mod_exp_zero_test(&mod_exp_zero_test_data[i], ctx, | ||
170 | use_random); | ||
171 | |||
172 | failed |= bn_mod_exp_zero_word_test(ctx); | ||
173 | |||
174 | BN_CTX_free(ctx); | ||
175 | |||
176 | return failed; | ||
177 | } | ||
178 | |||
179 | int | ||
180 | main(void) | ||
181 | { | ||
182 | int failed = 0; | ||
183 | |||
184 | failed |= run_bn_mod_exp_zero_tests(); | ||
185 | |||
186 | return failed; | ||
187 | } | ||