diff options
| author | tb <> | 2022-12-02 17:33:38 +0000 |
|---|---|---|
| committer | tb <> | 2022-12-02 17:33:38 +0000 |
| commit | 13d69de281b7e47a8e1e7bcff967d71513adb4ef (patch) | |
| tree | a2bd6c766ad880828089a263ca315875c5d70a85 /src | |
| parent | 66b0d4ab48cd1eed29fcbe7a4e84ff817b73ba8d (diff) | |
| download | openbsd-13d69de281b7e47a8e1e7bcff967d71513adb4ef.tar.gz openbsd-13d69de281b7e47a8e1e7bcff967d71513adb4ef.tar.bz2 openbsd-13d69de281b7e47a8e1e7bcff967d71513adb4ef.zip | |
Rewrite the tests that various modular exponentiation functions
compute a^0 = 0 (mod 1) for all a from scratch.
Diffstat (limited to '')
| -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 | } | ||
