1 /* 2 * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 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 8 */ 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 14 #include "internal/nelem.h" 15 16 #include <openssl/bio.h> 17 #include <openssl/bn.h> 18 #include <openssl/rand.h> 19 #include <openssl/err.h> 20 21 #include "testutil.h" 22 23 #define NUM_BITS (BN_BITS2 * 4) 24 25 #define BN_print_var(v) test_output_bignum(#v, v) 26 27 /* 28 * Test that r == 0 in test_exp_mod_zero(). Returns one on success, 29 * returns zero and prints debug output otherwise. 30 */ 31 static int a_is_zero_mod_one(const char *method, const BIGNUM *r, 32 const BIGNUM *a) 33 { 34 if (!BN_is_zero(r)) { 35 TEST_error("%s failed: a ** 0 mod 1 = r (should be 0)", method); 36 BN_print_var(a); 37 BN_print_var(r); 38 return 0; 39 } 40 return 1; 41 } 42 43 /* 44 * test_mod_exp_zero tests that x**0 mod 1 == 0. It returns zero on success. 45 */ 46 static int test_mod_exp_zero(void) 47 { 48 BIGNUM *a = NULL, *p = NULL, *m = NULL; 49 BIGNUM *r = NULL; 50 BN_ULONG one_word = 1; 51 BN_CTX *ctx = BN_CTX_new(); 52 int ret = 1, failed = 0; 53 54 if (!TEST_ptr(m = BN_new()) 55 || !TEST_ptr(a = BN_new()) 56 || !TEST_ptr(p = BN_new()) 57 || !TEST_ptr(r = BN_new())) 58 goto err; 59 60 BN_one(m); 61 BN_one(a); 62 BN_zero(p); 63 64 if (!TEST_true(BN_rand(a, 1024, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))) 65 goto err; 66 67 if (!TEST_true(BN_mod_exp(r, a, p, m, ctx))) 68 goto err; 69 70 if (!TEST_true(a_is_zero_mod_one("BN_mod_exp", r, a))) 71 failed = 1; 72 73 if (!TEST_true(BN_mod_exp_recp(r, a, p, m, ctx))) 74 goto err; 75 76 if (!TEST_true(a_is_zero_mod_one("BN_mod_exp_recp", r, a))) 77 failed = 1; 78 79 if (!TEST_true(BN_mod_exp_simple(r, a, p, m, ctx))) 80 goto err; 81 82 if (!TEST_true(a_is_zero_mod_one("BN_mod_exp_simple", r, a))) 83 failed = 1; 84 85 if (!TEST_true(BN_mod_exp_mont(r, a, p, m, ctx, NULL))) 86 goto err; 87 88 if (!TEST_true(a_is_zero_mod_one("BN_mod_exp_mont", r, a))) 89 failed = 1; 90 91 if (!TEST_true(BN_mod_exp_mont_consttime(r, a, p, m, ctx, NULL))) 92 goto err; 93 94 if (!TEST_true(a_is_zero_mod_one("BN_mod_exp_mont_consttime", r, a))) 95 failed = 1; 96 97 /* 98 * A different codepath exists for single word multiplication 99 * in non-constant-time only. 100 */ 101 if (!TEST_true(BN_mod_exp_mont_word(r, one_word, p, m, ctx, NULL))) 102 goto err; 103 104 if (!TEST_BN_eq_zero(r)) { 105 TEST_error("BN_mod_exp_mont_word failed: " 106 "1 ** 0 mod 1 = r (should be 0)"); 107 BN_print_var(r); 108 goto err; 109 } 110 111 ret = !failed; 112 err: 113 BN_free(r); 114 BN_free(a); 115 BN_free(p); 116 BN_free(m); 117 BN_CTX_free(ctx); 118 119 return ret; 120 } 121 122 static int test_mod_exp(int round) 123 { 124 BN_CTX *ctx; 125 unsigned char c; 126 int ret = 0; 127 BIGNUM *r_mont = NULL; 128 BIGNUM *r_mont_const = NULL; 129 BIGNUM *r_recp = NULL; 130 BIGNUM *r_simple = NULL; 131 BIGNUM *a = NULL; 132 BIGNUM *b = NULL; 133 BIGNUM *m = NULL; 134 135 if (!TEST_ptr(ctx = BN_CTX_new())) 136 goto err; 137 138 if (!TEST_ptr(r_mont = BN_new()) 139 || !TEST_ptr(r_mont_const = BN_new()) 140 || !TEST_ptr(r_recp = BN_new()) 141 || !TEST_ptr(r_simple = BN_new()) 142 || !TEST_ptr(a = BN_new()) 143 || !TEST_ptr(b = BN_new()) 144 || !TEST_ptr(m = BN_new())) 145 goto err; 146 147 RAND_bytes(&c, 1); 148 c = (c % BN_BITS) - BN_BITS2; 149 BN_rand(a, NUM_BITS + c, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY); 150 151 RAND_bytes(&c, 1); 152 c = (c % BN_BITS) - BN_BITS2; 153 BN_rand(b, NUM_BITS + c, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY); 154 155 RAND_bytes(&c, 1); 156 c = (c % BN_BITS) - BN_BITS2; 157 BN_rand(m, NUM_BITS + c, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD); 158 159 if (!TEST_true(BN_mod(a, a, m, ctx)) 160 || !TEST_true(BN_mod(b, b, m, ctx)) 161 || !TEST_true(BN_mod_exp_mont(r_mont, a, b, m, ctx, NULL)) 162 || !TEST_true(BN_mod_exp_recp(r_recp, a, b, m, ctx)) 163 || !TEST_true(BN_mod_exp_simple(r_simple, a, b, m, ctx)) 164 || !TEST_true(BN_mod_exp_mont_consttime(r_mont_const, a, b, m, ctx, NULL))) 165 goto err; 166 167 if (!TEST_BN_eq(r_simple, r_mont) 168 || !TEST_BN_eq(r_simple, r_recp) 169 || !TEST_BN_eq(r_simple, r_mont_const)) { 170 if (BN_cmp(r_simple, r_mont) != 0) 171 TEST_info("simple and mont results differ"); 172 if (BN_cmp(r_simple, r_mont_const) != 0) 173 TEST_info("simple and mont const time results differ"); 174 if (BN_cmp(r_simple, r_recp) != 0) 175 TEST_info("simple and recp results differ"); 176 177 BN_print_var(a); 178 BN_print_var(b); 179 BN_print_var(m); 180 BN_print_var(r_simple); 181 BN_print_var(r_recp); 182 BN_print_var(r_mont); 183 BN_print_var(r_mont_const); 184 goto err; 185 } 186 187 ret = 1; 188 err: 189 BN_free(r_mont); 190 BN_free(r_mont_const); 191 BN_free(r_recp); 192 BN_free(r_simple); 193 BN_free(a); 194 BN_free(b); 195 BN_free(m); 196 BN_CTX_free(ctx); 197 198 return ret; 199 } 200 201 int setup_tests(void) 202 { 203 ADD_TEST(test_mod_exp_zero); 204 ADD_ALL_TESTS(test_mod_exp, 200); 205 return 1; 206 } 207