Coverage Report

Created: 2026-03-19 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/fipsmodule/bn/div.cc.inc
Line
Count
Source
1
// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/bn.h>
16
17
#include <assert.h>
18
#include <limits.h>
19
20
#include <openssl/err.h>
21
22
#include "internal.h"
23
24
#if (defined(OPENSSL_X86) || defined(OPENSSL_X86_64)) && defined(_MSC_VER) && \
25
    !defined(__clang__)
26
#define HAVE_MSVC_DIV_INTRINSICS
27
#include <immintrin.h>
28
#if defined(OPENSSL_X86)
29
#pragma intrinsic(_udiv64)
30
#else
31
#pragma intrinsic(_udiv128)
32
#endif
33
#endif
34
35
36
using namespace bssl;
37
38
// bn_div_words divides a double-width |h|,|l| by |d| and returns the result,
39
// which must fit in a |BN_ULONG|, i.e. |h < d|.
40
[[maybe_unused]]
41
0
static BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
42
0
  assert(h < d);
43
0
  BN_ULONG dh, dl, q, ret = 0, th, tl, t;
44
0
  int i, count = 2;
45
0
46
0
  if (d == 0) {
47
0
    return BN_MASK2;
48
0
  }
49
0
50
0
  i = BN_num_bits_word(d);
51
0
  assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
52
0
53
0
  i = BN_BITS2 - i;
54
0
  if (h >= d) {
55
0
    h -= d;
56
0
  }
57
0
58
0
  if (i) {
59
0
    d <<= i;
60
0
    h = (h << i) | (l >> (BN_BITS2 - i));
61
0
    l <<= i;
62
0
  }
63
0
  dh = (d & BN_MASK2h) >> BN_BITS4;
64
0
  dl = (d & BN_MASK2l);
65
0
  for (;;) {
66
0
    if ((h >> BN_BITS4) == dh) {
67
0
      q = BN_MASK2l;
68
0
    } else {
69
0
      q = h / dh;
70
0
    }
71
0
72
0
    th = q * dh;
73
0
    tl = dl * q;
74
0
    for (;;) {
75
0
      t = h - th;
76
0
      if ((t & BN_MASK2h) ||
77
0
          ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) {
78
0
        break;
79
0
      }
80
0
      q--;
81
0
      th -= dh;
82
0
      tl -= dl;
83
0
    }
84
0
    t = (tl >> BN_BITS4);
85
0
    tl = (tl << BN_BITS4) & BN_MASK2h;
86
0
    th += t;
87
0
88
0
    if (l < tl) {
89
0
      th++;
90
0
    }
91
0
    l -= tl;
92
0
    if (h < th) {
93
0
      h += d;
94
0
      q--;
95
0
    }
96
0
    h -= th;
97
0
98
0
    if (--count == 0) {
99
0
      break;
100
0
    }
101
0
102
0
    ret = q << BN_BITS4;
103
0
    h = (h << BN_BITS4) | (l >> BN_BITS4);
104
0
    l = (l & BN_MASK2l) << BN_BITS4;
105
0
  }
106
0
107
0
  ret |= q;
108
0
  return ret;
109
0
}
110
111
// bn_div_rem_words divides a double-width numerator (high half |nh| and low
112
// half |nl|) with a single-width divisor. It sets |*quotient_out| and
113
// |*rem_out| to be the quotient and numerator, respectively. The quotient must
114
// fit in a |BN_ULONG|, i.e. |nh < d|.
115
static void bn_div_rem_words(BN_ULONG *quotient_out, BN_ULONG *rem_out,
116
31.4M
                             BN_ULONG nh, BN_ULONG nl, BN_ULONG d) {
117
31.4M
  assert(nh < d);
118
  // This operation is the x86 and x86_64 DIV instruction, but it is difficult
119
  // for the compiler to emit it. Dividing a |BN_ULLONG| by a |BN_ULONG| does
120
  // not work because, a priori, the quotient may not fit in |BN_ULONG| and DIV
121
  // will trap on overflow, not truncate. The compiler will instead emit a call
122
  // to a more expensive support function (e.g. |__udivdi3|). Thus we use inline
123
  // assembly or intrinsics to get the instruction.
124
  //
125
  // These is specific to x86 and x86_64; Arm and RISC-V do not have double-wide
126
  // division instructions.
127
#if defined(BN_CAN_USE_INLINE_ASM) && defined(OPENSSL_X86)
128
  __asm__ volatile("divl %4"
129
                   : "=a"(*quotient_out), "=d"(*rem_out)
130
                   : "a"(nl), "d"(nh), "rm"(d)
131
                   : "cc");
132
#elif defined(BN_CAN_USE_INLINE_ASM) && defined(OPENSSL_X86_64)
133
31.4M
  __asm__ volatile("divq %4"
134
31.4M
                   : "=a"(*quotient_out), "=d"(*rem_out)
135
31.4M
                   : "a"(nl), "d"(nh), "rm"(d)
136
31.4M
                   : "cc");
137
#elif defined(HAVE_MSVC_DIV_INTRINSICS) && defined(OPENSSL_X86)
138
  BN_ULLONG n = (((BN_ULLONG)nh) << BN_BITS2) | nl;
139
  unsigned rem;
140
  *quotient_out = _udiv64(n, d, &rem);
141
  *rem_out = rem;
142
#elif defined(HAVE_MSVC_DIV_INTRINSICS) && defined(OPENSSL_X86_64)
143
  unsigned __int64 rem;
144
  *quotient_out = _udiv128(nh, nl, d, &rem);
145
  *rem_out = rem;
146
#else
147
#if defined(BN_CAN_DIVIDE_ULLONG)
148
  BN_ULLONG n = (((BN_ULLONG)nh) << BN_BITS2) | nl;
149
  *quotient_out = (BN_ULONG)(n / d);
150
#else
151
  *quotient_out = bn_div_words(nh, nl, d);
152
#endif  // BN_CAN_DIVIDE_ULLONG
153
  *rem_out = nl - (*quotient_out * d);
154
#endif
155
31.4M
}
156
157
int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
158
6.26M
           const BIGNUM *divisor, BN_CTX *ctx) {
159
  // This function implements long division, per Knuth, The Art of Computer
160
  // Programming, Volume 2, Chapter 4.3.1, Algorithm D. This algorithm only
161
  // divides non-negative integers, but we round towards zero, so we divide
162
  // absolute values and adjust the signs separately.
163
  //
164
  // Inputs to this function are assumed public and may be leaked by timing and
165
  // cache side channels. Division with secret inputs should use other
166
  // implementation strategies such as Montgomery reduction.
167
6.26M
  if (BN_is_zero(divisor)) {
168
0
    OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
169
0
    return 0;
170
0
  }
171
172
6.26M
  BN_CTXScope scope(ctx);
173
6.26M
  BIGNUM *tmp = BN_CTX_get(ctx);
174
6.26M
  BIGNUM *snum = BN_CTX_get(ctx);
175
6.26M
  BIGNUM *sdiv = BN_CTX_get(ctx);
176
6.26M
  BIGNUM *res = quotient == nullptr ? BN_CTX_get(ctx) : quotient;
177
6.26M
  int norm_shift, num_n, loop, div_n;
178
6.26M
  BN_ULONG d0, d1;
179
6.26M
  if (tmp == nullptr || snum == nullptr || sdiv == nullptr || res == nullptr) {
180
0
    return 0;
181
0
  }
182
183
  // Knuth step D1: Normalise the numbers such that the divisor's MSB is set.
184
  // This ensures, in Knuth's terminology, that v1 >= b/2, needed for the
185
  // quotient estimation step.
186
6.26M
  norm_shift = BN_BITS2 - (BN_num_bits(divisor) % BN_BITS2);
187
6.26M
  if (!BN_lshift(sdiv, divisor, norm_shift) ||
188
6.26M
      !BN_lshift(snum, numerator, norm_shift)) {
189
0
    return 0;
190
0
  }
191
192
  // This algorithm relies on |sdiv| being minimal width. We do not use this
193
  // function on secret inputs, so leaking this is fine. Also minimize |snum| to
194
  // avoid looping on leading zeros, as we're not trying to be leak-free.
195
6.26M
  bn_set_minimal_width(sdiv);
196
6.26M
  bn_set_minimal_width(snum);
197
6.26M
  div_n = sdiv->width;
198
6.26M
  d0 = sdiv->d[div_n - 1];
199
6.26M
  d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];
200
6.26M
  assert(d0 & (((BN_ULONG)1) << (BN_BITS2 - 1)));
201
202
  // Extend |snum| with zeros to satisfy the long division invariants:
203
  // - |snum| must have at least |div_n| + 1 words.
204
  // - |snum|'s most significant word must be zero to guarantee the first loop
205
  //   iteration works with a prefix greater than |sdiv|. (This is the extra u0
206
  //   digit in Knuth step D1.)
207
6.26M
  num_n = snum->width <= div_n ? div_n + 1 : snum->width + 1;
208
6.26M
  if (!bn_resize_words(snum, num_n)) {
209
0
    return 0;
210
0
  }
211
212
  // Knuth step D2: The quotient's width is the difference between numerator and
213
  // denominator. Also set up its sign and size a temporary for the loop.
214
6.26M
  loop = num_n - div_n;
215
6.26M
  res->neg = snum->neg ^ sdiv->neg;
216
6.26M
  if (!bn_wexpand(res, loop) ||  //
217
6.26M
      !bn_wexpand(tmp, div_n + 1)) {
218
0
    return 0;
219
0
  }
220
6.26M
  res->width = loop;
221
222
  // Knuth steps D2 through D7: Compute the quotient with a word-by-word long
223
  // division. Note that Knuth indexes words from most to least significant, so
224
  // our index is reversed. Each loop iteration computes res->d[i] of the
225
  // quotient and updates snum with the running remainder. Before each loop
226
  // iteration, the div_n words beginning at snum->d[i+1] must be less than
227
  // snum.
228
37.8M
  for (int i = loop - 1; i >= 0; i--) {
229
    // The next word of the quotient, q, is floor(wnum / sdiv), where wnum is
230
    // the div_n + 1 words beginning at snum->d[i]. i starts at
231
    // num_n - div_n - 1, so there are at least div_n + 1 words available.
232
    //
233
    // Knuth step D3: Compute q', an estimate of q by looking at the top words
234
    // of wnum and sdiv. We must estimate such that q' = q or q' = q + 1.
235
31.5M
    BN_ULONG q, rm = 0;
236
31.5M
    BN_ULONG *wnum = snum->d + i;
237
31.5M
    BN_ULONG n0 = wnum[div_n];
238
31.5M
    BN_ULONG n1 = wnum[div_n - 1];
239
31.5M
    if (n0 == d0) {
240
      // Estimate q' = b - 1, where b is the base.
241
115k
      q = BN_MASK2;
242
      // Knuth also runs the fixup routine in this case, but this would require
243
      // computing rm and is unnecessary. q' is already close enough. That is,
244
      // the true quotient, q is either b - 1 or b - 2.
245
      //
246
      // By the loop invariant, q <= b - 1, so we must show that q >= b - 2. We
247
      // do this by showing wnum / sdiv >= b - 2. Suppose wnum / sdiv < b - 2.
248
      // wnum and sdiv have the same most significant word, so:
249
      //
250
      //    wnum >= n0 * b^div_n
251
      //    sdiv <  (n0 + 1) * b^(d_div - 1)
252
      //
253
      // Thus:
254
      //
255
      //    b - 2 > wnum / sdiv
256
      //          > (n0 * b^div_n) / (n0 + 1) * b^(div_n - 1)
257
      //          = (n0 * b) / (n0 + 1)
258
      //
259
      //         (n0 + 1) * (b - 2) > n0 * b
260
      //    n0 * b + b - 2 * n0 - 2 > n0 * b
261
      //                      b - 2 > 2 * n0
262
      //                    b/2 - 1 > n0
263
      //
264
      // This contradicts the normalization condition, so q >= b - 2 and our
265
      // estimate is close enough.
266
31.4M
    } else {
267
      // Estimate q' = floor(n0n1 / d0). Per Theorem B, q' - 2 <= q <= q', which
268
      // is slightly outside of our bounds.
269
31.4M
      assert(n0 < d0);
270
31.4M
      bn_div_rem_words(&q, &rm, n0, n1, d0);
271
272
      // Fix the estimate by examining one more word and adjusting q' as needed.
273
      // This is the second half of step D3 and is sufficient per exercises 19,
274
      // 20, and 21. Although only one iteration is needed to correct q + 2 to
275
      // q + 1, Knuth uses a loop. A loop will often also correct q + 1 to q,
276
      // saving the slightly more expensive underflow handling below.
277
31.4M
      if (div_n > 1) {
278
30.8M
        BN_ULONG n2 = wnum[div_n - 2];
279
30.8M
#ifdef BN_ULLONG
280
30.8M
        BN_ULLONG t2 = (BN_ULLONG)d1 * q;
281
31.0M
        for (;;) {
282
31.0M
          if (t2 <= ((((BN_ULLONG)rm) << BN_BITS2) | n2)) {
283
21.7M
            break;
284
21.7M
          }
285
9.26M
          q--;
286
9.26M
          rm += d0;
287
9.26M
          if (rm < d0) {
288
            // If rm overflows, the true value exceeds BN_ULONG and the next
289
            // t2 comparison should exit the loop.
290
9.02M
            break;
291
9.02M
          }
292
240k
          t2 -= d1;
293
240k
        }
294
#else   // !BN_ULLONG
295
        BN_ULONG t2l, t2h;
296
        BN_UMULT_LOHI(t2l, t2h, d1, q);
297
        for (;;) {
298
          if (t2h < rm || (t2h == rm && t2l <= n2)) {
299
            break;
300
          }
301
          q--;
302
          rm += d0;
303
          if (rm < d0) {
304
            // If rm overflows, the true value exceeds BN_ULONG and the next
305
            // t2 comparison should exit the loop.
306
            break;
307
          }
308
          if (t2l < d1) {
309
            t2h--;
310
          }
311
          t2l -= d1;
312
        }
313
#endif  // !BN_ULLONG
314
30.8M
      }
315
31.4M
    }
316
317
    // Knuth step D4 through D6: Now q' = q or q' = q + 1, and
318
    // -sdiv < wnum - sdiv * q < sdiv. If q' = q + 1, the subtraction will
319
    // underflow, and we fix it up below.
320
31.5M
    tmp->d[div_n] = bn_mul_words(tmp->d, sdiv->d, div_n, q);
321
31.5M
    if (bn_sub_words(wnum, wnum, tmp->d, div_n + 1)) {
322
114k
      q--;
323
      // The final addition is expected to overflow, canceling the underflow.
324
114k
      wnum[div_n] += bn_add_words(wnum, wnum, sdiv->d, div_n);
325
114k
    }
326
327
    // q is now correct, and wnum has been updated to the running remainder.
328
31.5M
    res->d[i] = q;
329
31.5M
  }
330
331
  // Trim leading zeros and correct any negative zeros.
332
6.26M
  bn_set_minimal_width(snum);
333
6.26M
  bn_set_minimal_width(res);
334
335
  // Knuth step D8: Unnormalize. snum now contains the remainder.
336
6.26M
  if (rem != nullptr && !BN_rshift(rem, snum, norm_shift)) {
337
0
    return 0;
338
0
  }
339
340
6.26M
  return 1;
341
6.26M
}
342
343
5.97M
int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) {
344
5.97M
  if (!(BN_mod(r, m, d, ctx))) {
345
0
    return 0;
346
0
  }
347
5.97M
  if (!r->neg) {
348
5.97M
    return 1;
349
5.97M
  }
350
351
  // now -d < r < 0, so we have to set r := r + d. Ignoring the sign bits, this
352
  // is r = d - r.
353
2.63k
  return BN_usub(r, d, r);
354
5.97M
}
355
356
BN_ULONG bssl::bn_reduce_once(BN_ULONG *r, const BN_ULONG *a, BN_ULONG carry,
357
564k
                              const BN_ULONG *m, size_t num) {
358
564k
  assert(r != a);
359
  // |r| = |a| - |m|. |bn_sub_words| performs the bulk of the subtraction, and
360
  // then we apply the borrow to |carry|.
361
564k
  carry -= bn_sub_words(r, a, m, num);
362
  // We know 0 <= |a| < 2*|m|, so -|m| <= |r| < |m|.
363
  //
364
  // If 0 <= |r| < |m|, |r| fits in |num| words and |carry| is zero. We then
365
  // wish to select |r| as the answer. Otherwise -m <= r < 0 and we wish to
366
  // return |r| + |m|, or |a|. |carry| must then be -1 or all ones. In both
367
  // cases, |carry| is a suitable input to |bn_select_words|.
368
  //
369
  // Although |carry| may be one if it was one on input and |bn_sub_words|
370
  // returns zero, this would give |r| > |m|, violating our input assumptions.
371
564k
  declassify_assert(carry + 1 <= 1);
372
564k
  bn_select_words(r, carry, a /* r < 0 */, r /* r >= 0 */, num);
373
564k
  return carry;
374
564k
}
375
376
BN_ULONG bssl::bn_reduce_once_in_place(BN_ULONG *r, BN_ULONG carry,
377
                                       const BN_ULONG *m, BN_ULONG *tmp,
378
120M
                                       size_t num) {
379
  // See |bn_reduce_once| for why this logic works.
380
120M
  carry -= bn_sub_words(tmp, r, m, num);
381
120M
  declassify_assert(carry + 1 <= 1);
382
120M
  bn_select_words(r, carry, r /* tmp < 0 */, tmp /* tmp >= 0 */, num);
383
120M
  return carry;
384
120M
}
385
386
void bssl::bn_mod_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
387
82.0M
                            const BN_ULONG *m, BN_ULONG *tmp, size_t num) {
388
  // r = a - b
389
82.0M
  BN_ULONG borrow = bn_sub_words(r, a, b, num);
390
  // tmp = a - b + m
391
82.0M
  bn_add_words(tmp, r, m, num);
392
82.0M
  bn_select_words(r, 0 - borrow, tmp /* r < 0 */, r /* r >= 0 */, num);
393
82.0M
}
394
395
void bssl::bn_mod_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
396
119M
                            const BN_ULONG *m, BN_ULONG *tmp, size_t num) {
397
119M
  BN_ULONG carry = bn_add_words(r, a, b, num);
398
119M
  bn_reduce_once_in_place(r, carry, m, tmp, num);
399
119M
}
400
401
int bssl::bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder,
402
                           const BIGNUM *numerator, const BIGNUM *divisor,
403
1.10k
                           unsigned divisor_min_bits, BN_CTX *ctx) {
404
1.10k
  if (BN_is_negative(numerator) || BN_is_negative(divisor)) {
405
0
    OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
406
0
    return 0;
407
0
  }
408
1.10k
  if (BN_is_zero(divisor)) {
409
0
    OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
410
0
    return 0;
411
0
  }
412
413
  // This function implements long division in binary. It is not very efficient,
414
  // but it is simple, easy to make constant-time, and performant enough for RSA
415
  // key generation.
416
417
1.10k
  BN_CTXScope scope(ctx);
418
1.10k
  BIGNUM *q = quotient, *r = remainder;
419
1.10k
  if (quotient == nullptr || quotient == numerator || quotient == divisor) {
420
1.10k
    q = BN_CTX_get(ctx);
421
1.10k
  }
422
1.10k
  if (remainder == nullptr || remainder == numerator || remainder == divisor) {
423
715
    r = BN_CTX_get(ctx);
424
715
  }
425
1.10k
  BIGNUM *tmp = BN_CTX_get(ctx);
426
1.10k
  int initial_words;
427
1.10k
  if (q == nullptr || r == nullptr || tmp == nullptr ||
428
1.10k
      !bn_wexpand(q, numerator->width) || !bn_wexpand(r, divisor->width) ||
429
1.10k
      !bn_wexpand(tmp, divisor->width)) {
430
0
    return 0;
431
0
  }
432
433
1.10k
  OPENSSL_memset(q->d, 0, numerator->width * sizeof(BN_ULONG));
434
1.10k
  q->width = numerator->width;
435
1.10k
  q->neg = 0;
436
437
1.10k
  OPENSSL_memset(r->d, 0, divisor->width * sizeof(BN_ULONG));
438
1.10k
  r->width = divisor->width;
439
1.10k
  r->neg = 0;
440
441
  // Incorporate |numerator| into |r|, one bit at a time, reducing after each
442
  // step. We maintain the invariant that |0 <= r < divisor| and
443
  // |q * divisor + r = n| where |n| is the portion of |numerator| incorporated
444
  // so far.
445
  //
446
  // First, we short-circuit the loop: if we know |divisor| has at least
447
  // |divisor_min_bits| bits, the top |divisor_min_bits - 1| can be incorporated
448
  // without reductions. This significantly speeds up |RSA_check_key|. For
449
  // simplicity, we round down to a whole number of words.
450
1.10k
  declassify_assert(divisor_min_bits <= BN_num_bits(divisor));
451
1.10k
  initial_words = 0;
452
1.10k
  if (divisor_min_bits > 0) {
453
1.10k
    initial_words = (divisor_min_bits - 1) / BN_BITS2;
454
1.10k
    if (initial_words > numerator->width) {
455
82
      initial_words = numerator->width;
456
82
    }
457
1.10k
    OPENSSL_memcpy(r->d, numerator->d + numerator->width - initial_words,
458
1.10k
                   initial_words * sizeof(BN_ULONG));
459
1.10k
  }
460
461
12.9k
  for (int i = numerator->width - initial_words - 1; i >= 0; i--) {
462
770k
    for (int bit = BN_BITS2 - 1; bit >= 0; bit--) {
463
      // Incorporate the next bit of the numerator, by computing
464
      // r = 2*r or 2*r + 1. Note the result fits in one more word. We store the
465
      // extra word in |carry|.
466
758k
      BN_ULONG carry = bn_add_words(r->d, r->d, r->d, divisor->width);
467
758k
      r->d[0] |= (numerator->d[i] >> bit) & 1;
468
      // |r| was previously fully-reduced, so we know:
469
      //      2*0 <= r <= 2*(divisor-1) + 1
470
      //        0 <= r <= 2*divisor - 1 < 2*divisor.
471
      // Thus |r| satisfies the preconditions for |bn_reduce_once_in_place|.
472
758k
      BN_ULONG subtracted = bn_reduce_once_in_place(r->d, carry, divisor->d,
473
758k
                                                    tmp->d, divisor->width);
474
      // The corresponding bit of the quotient is set iff we needed to subtract.
475
758k
      q->d[i] |= (~subtracted & 1) << bit;
476
758k
    }
477
11.8k
  }
478
479
1.10k
  if ((quotient != nullptr && !BN_copy(quotient, q)) ||
480
1.10k
      (remainder != nullptr && !BN_copy(remainder, r))) {
481
0
    return 0;
482
0
  }
483
484
1.10k
  return 1;
485
1.10k
}
486
487
44.7k
static BIGNUM *bn_scratch_space_from_ctx(size_t width, BN_CTX *ctx) {
488
44.7k
  BIGNUM *ret = BN_CTX_get(ctx);
489
44.7k
  if (ret == nullptr || !bn_wexpand(ret, width)) {
490
0
    return nullptr;
491
0
  }
492
44.7k
  ret->neg = 0;
493
44.7k
  ret->width = (int)width;
494
44.7k
  return ret;
495
44.7k
}
496
497
// bn_resized_from_ctx returns |bn| with width at least |width| or NULL on
498
// error. This is so it may be used with low-level "words" functions. If
499
// necessary, it allocates a new |BIGNUM| with a lifetime of the current scope
500
// in |ctx|, so the caller does not need to explicitly free it. |bn| must fit in
501
// |width| words.
502
static const BIGNUM *bn_resized_from_ctx(const BIGNUM *bn, size_t width,
503
71.5k
                                         BN_CTX *ctx) {
504
71.5k
  if ((size_t)bn->width >= width) {
505
    // Any excess words must be zero.
506
71.2k
    assert(bn_fits_in_words(bn, width));
507
71.2k
    return bn;
508
71.2k
  }
509
321
  BIGNUM *ret = bn_scratch_space_from_ctx(width, ctx);
510
321
  if (ret == nullptr || !BN_copy(ret, bn) || !bn_resize_words(ret, width)) {
511
0
    return nullptr;
512
0
  }
513
321
  return ret;
514
321
}
515
516
int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
517
0
               BN_CTX *ctx) {
518
0
  if (!BN_add(r, a, b)) {
519
0
    return 0;
520
0
  }
521
0
  return BN_nnmod(r, r, m, ctx);
522
0
}
523
524
int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
525
0
                     const BIGNUM *m) {
526
0
  UniquePtr<BN_CTX> ctx(BN_CTX_new());
527
0
  return ctx != nullptr && bn_mod_add_consttime(r, a, b, m, ctx.get());
528
0
}
529
530
int bssl::bn_mod_add_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
531
11.6k
                               const BIGNUM *m, BN_CTX *ctx) {
532
11.6k
  BN_CTXScope scope(ctx);
533
11.6k
  a = bn_resized_from_ctx(a, m->width, ctx);
534
11.6k
  b = bn_resized_from_ctx(b, m->width, ctx);
535
11.6k
  BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx);
536
11.6k
  if (a == nullptr || b == nullptr || tmp == nullptr ||
537
11.6k
      !bn_wexpand(r, m->width)) {
538
0
    return 0;
539
0
  }
540
11.6k
  bn_mod_add_words(r->d, a->d, b->d, m->d, tmp->d, m->width);
541
11.6k
  r->width = m->width;
542
11.6k
  r->neg = 0;
543
11.6k
  return 1;
544
11.6k
}
545
546
int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
547
0
               BN_CTX *ctx) {
548
0
  if (!BN_sub(r, a, b)) {
549
0
    return 0;
550
0
  }
551
0
  return BN_nnmod(r, r, m, ctx);
552
0
}
553
554
int bssl::bn_mod_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
555
24.0k
                               const BIGNUM *m, BN_CTX *ctx) {
556
24.0k
  BN_CTXScope scope(ctx);
557
24.0k
  a = bn_resized_from_ctx(a, m->width, ctx);
558
24.0k
  b = bn_resized_from_ctx(b, m->width, ctx);
559
24.0k
  BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx);
560
24.0k
  if (a == nullptr || b == nullptr || tmp == nullptr ||
561
24.0k
      !bn_wexpand(r, m->width)) {
562
0
    return 0;
563
0
  }
564
24.0k
  bn_mod_sub_words(r->d, a->d, b->d, m->d, tmp->d, m->width);
565
24.0k
  r->width = m->width;
566
24.0k
  r->neg = 0;
567
24.0k
  return 1;
568
24.0k
}
569
570
int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
571
0
                     const BIGNUM *m) {
572
0
  UniquePtr<BN_CTX> ctx(BN_CTX_new());
573
0
  return ctx != nullptr && bn_mod_sub_consttime(r, a, b, m, ctx.get());
574
0
}
575
576
int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
577
5.60M
               BN_CTX *ctx) {
578
5.60M
  BN_CTXScope scope(ctx);
579
5.60M
  BIGNUM *t = BN_CTX_get(ctx);
580
5.60M
  if (t == nullptr) {
581
0
    return 0;
582
0
  }
583
584
5.60M
  if (a == b) {
585
5.35M
    if (!BN_sqr(t, a, ctx)) {
586
0
      return 0;
587
0
    }
588
5.35M
  } else {
589
250k
    if (!BN_mul(t, a, b, ctx)) {
590
0
      return 0;
591
0
    }
592
250k
  }
593
594
5.60M
  if (!BN_nnmod(r, t, m, ctx)) {
595
0
    return 0;
596
0
  }
597
598
5.60M
  return 1;
599
5.60M
}
600
601
274k
int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) {
602
274k
  if (!BN_sqr(r, a, ctx)) {
603
0
    return 0;
604
0
  }
605
606
  // r->neg == 0,  thus we don't need BN_nnmod
607
274k
  return BN_mod(r, r, m, ctx);
608
274k
}
609
610
int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
611
0
                  BN_CTX *ctx) {
612
0
  if (!BN_nnmod(r, a, m, ctx)) {
613
0
    return 0;
614
0
  }
615
616
0
  UniquePtr<BIGNUM> abs_m;
617
0
  if (m->neg) {
618
0
    abs_m.reset(BN_dup(m));
619
0
    if (abs_m == nullptr) {
620
0
      return 0;
621
0
    }
622
0
    abs_m->neg = 0;
623
0
  }
624
625
0
  return bn_mod_lshift_consttime(r, r, n, (abs_m ? abs_m.get() : m), ctx);
626
0
}
627
628
int bssl::bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n,
629
8.61k
                                  const BIGNUM *m, BN_CTX *ctx) {
630
8.61k
  if (!BN_copy(r, a) || !bn_resize_words(r, m->width)) {
631
0
    return 0;
632
0
  }
633
634
8.61k
  BN_CTXScope scope(ctx);
635
8.61k
  BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx);
636
8.61k
  if (tmp == nullptr) {
637
0
    return 0;
638
0
  }
639
311k
  for (int i = 0; i < n; i++) {
640
302k
    bn_mod_add_words(r->d, r->d, r->d, m->d, tmp->d, m->width);
641
302k
  }
642
8.61k
  r->neg = 0;
643
8.61k
  return 1;
644
8.61k
}
645
646
0
int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) {
647
0
  UniquePtr<BN_CTX> ctx(BN_CTX_new());
648
0
  return ctx != nullptr && bn_mod_lshift_consttime(r, a, n, m, ctx.get());
649
0
}
650
651
0
int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) {
652
0
  if (!BN_lshift1(r, a)) {
653
0
    return 0;
654
0
  }
655
656
0
  return BN_nnmod(r, r, m, ctx);
657
0
}
658
659
int bssl::bn_mod_lshift1_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *m,
660
3.89k
                                   BN_CTX *ctx) {
661
3.89k
  return bn_mod_add_consttime(r, a, a, m, ctx);
662
3.89k
}
663
664
0
int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) {
665
0
  UniquePtr<BN_CTX> ctx(BN_CTX_new());
666
0
  return ctx != nullptr && bn_mod_lshift1_consttime(r, a, m, ctx.get());
667
0
}
668
669
840
BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
670
840
  BN_ULONG ret = 0;
671
840
  int i, j;
672
673
840
  if (!w) {
674
    // actually this an error (division by zero)
675
0
    return (BN_ULONG)-1;
676
0
  }
677
678
840
  if (a->width == 0) {
679
0
    return 0;
680
0
  }
681
682
  // normalize input for |bn_div_rem_words|.
683
840
  j = BN_BITS2 - BN_num_bits_word(w);
684
840
  w <<= j;
685
840
  if (!BN_lshift(a, a, j)) {
686
0
    return (BN_ULONG)-1;
687
0
  }
688
689
1.68k
  for (i = a->width - 1; i >= 0; i--) {
690
840
    BN_ULONG l = a->d[i];
691
840
    BN_ULONG d;
692
840
    BN_ULONG unused_rem;
693
840
    bn_div_rem_words(&d, &unused_rem, ret, l, w);
694
840
    ret = l - (d * w);
695
840
    a->d[i] = d;
696
840
  }
697
698
840
  bn_set_minimal_width(a);
699
840
  ret >>= j;
700
840
  return ret;
701
840
}
702
703
0
BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
704
#ifndef BN_CAN_DIVIDE_ULLONG
705
  BN_ULONG ret = 0;
706
#else
707
0
  BN_ULLONG ret = 0;
708
0
#endif
709
0
  int i;
710
711
0
  if (w == 0) {
712
0
    return (BN_ULONG)-1;
713
0
  }
714
715
#ifndef BN_CAN_DIVIDE_ULLONG
716
  // If |w| is too long and we don't have |BN_ULLONG| division then we need to
717
  // fall back to using |BN_div_word|.
718
  if (w > ((BN_ULONG)1 << BN_BITS4)) {
719
    BIGNUM *tmp = BN_dup(a);
720
    if (tmp == nullptr) {
721
      return (BN_ULONG)-1;
722
    }
723
    ret = BN_div_word(tmp, w);
724
    BN_free(tmp);
725
    return ret;
726
  }
727
#endif
728
729
0
  for (i = a->width - 1; i >= 0; i--) {
730
#ifndef BN_CAN_DIVIDE_ULLONG
731
    ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
732
    ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
733
#else
734
0
    ret = (BN_ULLONG)(((ret << (BN_ULLONG)BN_BITS2) | a->d[i]) % (BN_ULLONG)w);
735
0
#endif
736
0
  }
737
0
  return (BN_ULONG)ret;
738
0
}