• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright 1995-2016 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 <openssl/bn.h>
11
12#include <openssl/err.h>
13
14#include "internal.h"
15
16
17int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
18                       const BIGNUM *n, BN_CTX *ctx) {
19  *out_no_inverse = 0;
20
21  if (!BN_is_odd(n)) {
22    OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
23    return 0;
24  }
25
26  if (BN_is_negative(a) || BN_cmp(a, n) >= 0) {
27    OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
28    return 0;
29  }
30
31  BIGNUM *A, *B, *X, *Y;
32  int ret = 0;
33  int sign;
34
35  BN_CTX_start(ctx);
36  A = BN_CTX_get(ctx);
37  B = BN_CTX_get(ctx);
38  X = BN_CTX_get(ctx);
39  Y = BN_CTX_get(ctx);
40  BIGNUM *R = out;
41  if (Y == NULL) {
42    goto err;
43  }
44
45  BN_zero(Y);
46  if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
47    goto err;
48  }
49  A->neg = 0;
50  sign = -1;
51  // From  B = a mod |n|,  A = |n|  it follows that
52  //
53  //      0 <= B < A,
54  //     -sign*X*a  ==  B   (mod |n|),
55  //      sign*Y*a  ==  A   (mod |n|).
56
57  // Binary inversion algorithm; requires odd modulus. This is faster than the
58  // general algorithm if the modulus is sufficiently small (about 400 .. 500
59  // bits on 32-bit systems, but much more on 64-bit systems)
60  int shift;
61
62  while (!BN_is_zero(B)) {
63    //      0 < B < |n|,
64    //      0 < A <= |n|,
65    // (1) -sign*X*a  ==  B   (mod |n|),
66    // (2)  sign*Y*a  ==  A   (mod |n|)
67
68    // Now divide  B  by the maximum possible power of two in the integers,
69    // and divide  X  by the same value mod |n|.
70    // When we're done, (1) still holds.
71    shift = 0;
72    while (!BN_is_bit_set(B, shift)) {
73      // note that 0 < B
74      shift++;
75
76      if (BN_is_odd(X)) {
77        if (!BN_uadd(X, X, n)) {
78          goto err;
79        }
80      }
81      // now X is even, so we can easily divide it by two
82      if (!BN_rshift1(X, X)) {
83        goto err;
84      }
85    }
86    if (shift > 0) {
87      if (!BN_rshift(B, B, shift)) {
88        goto err;
89      }
90    }
91
92    // Same for A and Y. Afterwards, (2) still holds.
93    shift = 0;
94    while (!BN_is_bit_set(A, shift)) {
95      // note that 0 < A
96      shift++;
97
98      if (BN_is_odd(Y)) {
99        if (!BN_uadd(Y, Y, n)) {
100          goto err;
101        }
102      }
103      // now Y is even
104      if (!BN_rshift1(Y, Y)) {
105        goto err;
106      }
107    }
108    if (shift > 0) {
109      if (!BN_rshift(A, A, shift)) {
110        goto err;
111      }
112    }
113
114    // We still have (1) and (2).
115    // Both  A  and  B  are odd.
116    // The following computations ensure that
117    //
118    //     0 <= B < |n|,
119    //      0 < A < |n|,
120    // (1) -sign*X*a  ==  B   (mod |n|),
121    // (2)  sign*Y*a  ==  A   (mod |n|),
122    //
123    // and that either  A  or  B  is even in the next iteration.
124    if (BN_ucmp(B, A) >= 0) {
125      // -sign*(X + Y)*a == B - A  (mod |n|)
126      if (!BN_uadd(X, X, Y)) {
127        goto err;
128      }
129      // NB: we could use BN_mod_add_quick(X, X, Y, n), but that
130      // actually makes the algorithm slower
131      if (!BN_usub(B, B, A)) {
132        goto err;
133      }
134    } else {
135      //  sign*(X + Y)*a == A - B  (mod |n|)
136      if (!BN_uadd(Y, Y, X)) {
137        goto err;
138      }
139      // as above, BN_mod_add_quick(Y, Y, X, n) would slow things down
140      if (!BN_usub(A, A, B)) {
141        goto err;
142      }
143    }
144  }
145
146  if (!BN_is_one(A)) {
147    *out_no_inverse = 1;
148    OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
149    goto err;
150  }
151
152  // The while loop (Euclid's algorithm) ends when
153  //      A == gcd(a,n);
154  // we have
155  //       sign*Y*a  ==  A  (mod |n|),
156  // where  Y  is non-negative.
157
158  if (sign < 0) {
159    if (!BN_sub(Y, n, Y)) {
160      goto err;
161    }
162  }
163  // Now  Y*a  ==  A  (mod |n|).
164
165  // Y*a == 1  (mod |n|)
166  if (Y->neg || BN_ucmp(Y, n) >= 0) {
167    if (!BN_nnmod(Y, Y, n, ctx)) {
168      goto err;
169    }
170  }
171  if (!BN_copy(R, Y)) {
172    goto err;
173  }
174
175  ret = 1;
176
177err:
178  BN_CTX_end(ctx);
179  return ret;
180}
181
182BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
183                       BN_CTX *ctx) {
184  BIGNUM *new_out = NULL;
185  if (out == NULL) {
186    new_out = BN_new();
187    if (new_out == NULL) {
188      return NULL;
189    }
190    out = new_out;
191  }
192
193  int ok = 0;
194  BIGNUM *a_reduced = NULL;
195  if (a->neg || BN_ucmp(a, n) >= 0) {
196    a_reduced = BN_dup(a);
197    if (a_reduced == NULL) {
198      goto err;
199    }
200    if (!BN_nnmod(a_reduced, a_reduced, n, ctx)) {
201      goto err;
202    }
203    a = a_reduced;
204  }
205
206  int no_inverse;
207  if (!BN_is_odd(n)) {
208    if (!bn_mod_inverse_consttime(out, &no_inverse, a, n, ctx)) {
209      goto err;
210    }
211  } else if (!BN_mod_inverse_odd(out, &no_inverse, a, n, ctx)) {
212    goto err;
213  }
214
215  ok = 1;
216
217err:
218  if (!ok) {
219    BN_free(new_out);
220    out = NULL;
221  }
222  BN_free(a_reduced);
223  return out;
224}
225
226int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
227                           const BN_MONT_CTX *mont, BN_CTX *ctx) {
228  *out_no_inverse = 0;
229
230  // |a| is secret, but it is required to be in range, so these comparisons may
231  // be leaked.
232  if (BN_is_negative(a) ||
233      constant_time_declassify_int(BN_cmp(a, &mont->N) >= 0)) {
234    OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
235    return 0;
236  }
237
238  int ret = 0;
239  BIGNUM blinding_factor;
240  BN_init(&blinding_factor);
241
242  // |BN_mod_inverse_odd| is leaky, so generate a secret blinding factor and
243  // blind |a|. This works because (ar)^-1 * r = a^-1, supposing r is
244  // invertible. If r is not invertible, this function will fail. However, we
245  // only use this in RSA, where stumbling on an uninvertible element means
246  // stumbling on the key's factorization. That is, if this function fails, the
247  // RSA key was not actually a product of two large primes.
248  //
249  // TODO(crbug.com/boringssl/677): When the PRNG output is marked secret by
250  // default, the explicit |bn_secret| call can be removed.
251  if (!BN_rand_range_ex(&blinding_factor, 1, &mont->N)) {
252    goto err;
253  }
254  bn_secret(&blinding_factor);
255  if (!BN_mod_mul_montgomery(out, &blinding_factor, a, mont, ctx)) {
256    goto err;
257  }
258
259  // Once blinded, |out| is no longer secret, so it may be passed to a leaky
260  // mod inverse function. Note |blinding_factor| is secret, so |out| will be
261  // secret again after multiplying.
262  bn_declassify(out);
263  if (!BN_mod_inverse_odd(out, out_no_inverse, out, &mont->N, ctx) ||
264      !BN_mod_mul_montgomery(out, &blinding_factor, out, mont, ctx)) {
265    goto err;
266  }
267
268  ret = 1;
269
270err:
271  BN_free(&blinding_factor);
272  return ret;
273}
274
275int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
276                         BN_CTX *ctx, const BN_MONT_CTX *mont_p) {
277  BN_CTX_start(ctx);
278  BIGNUM *p_minus_2 = BN_CTX_get(ctx);
279  int ok = p_minus_2 != NULL && BN_copy(p_minus_2, p) &&
280           BN_sub_word(p_minus_2, 2) &&
281           BN_mod_exp_mont(out, a, p_minus_2, p, ctx, mont_p);
282  BN_CTX_end(ctx);
283  return ok;
284}
285
286int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
287                                BN_CTX *ctx, const BN_MONT_CTX *mont_p) {
288  BN_CTX_start(ctx);
289  BIGNUM *p_minus_2 = BN_CTX_get(ctx);
290  int ok = p_minus_2 != NULL && BN_copy(p_minus_2, p) &&
291           BN_sub_word(p_minus_2, 2) &&
292           BN_mod_exp_mont_consttime(out, a, p_minus_2, p, ctx, mont_p);
293  BN_CTX_end(ctx);
294  return ok;
295}
296