| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/bn/bn_mod.c | 
| Source code | Switch to Preprocessed file | 
| Line | Source | Count | ||||||
|---|---|---|---|---|---|---|---|---|
| 1 | /* | - | ||||||
| 2 | * Copyright 1998-2018 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 "internal/cryptlib.h" | - | ||||||
| 11 | #include "bn_lcl.h" | - | ||||||
| 12 | - | |||||||
| 13 | int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) | - | ||||||
| 14 | { | - | ||||||
| 15 | /* | - | ||||||
| 16 | * like BN_mod, but returns non-negative remainder (i.e., 0 <= r < |d| | - | ||||||
| 17 | * always holds) | - | ||||||
| 18 | */ | - | ||||||
| 19 | - | |||||||
| 20 |     if (!(BN_mod(r, m, d, ctx)))
  | 2-4223126 | ||||||
| 21 |         return 0; executed 2 times by 1 test:  return 0;Executed by: 
  | 2 | ||||||
| 22 |     if (!r->neg)
  | 46681-4176445 | ||||||
| 23 |         return 1; executed 4176445 times by 2 tests:  return 1;Executed by: 
  | 4176445 | ||||||
| 24 | /* now -|d| < r < 0, so we have to set r := r + |d| */ | - | ||||||
| 25 |     return (d->neg ? BN_sub : BN_add) (r, r, d); executed 46681 times by 2 tests:  return (d->neg ? BN_sub : BN_add) (r, r, d);Executed by: 
 
  | 208-46681 | ||||||
| 26 | } | - | ||||||
| 27 | - | |||||||
| 28 | int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, | - | ||||||
| 29 | BN_CTX *ctx) | - | ||||||
| 30 | { | - | ||||||
| 31 |     if (!BN_add(r, a, b))
  | 0-104 | ||||||
| 32 |         return 0; never executed:  return 0; | 0 | ||||||
| 33 |     return BN_nnmod(r, r, m, ctx); executed 104 times by 2 tests:  return BN_nnmod(r, r, m, ctx);Executed by: 
  | 104 | ||||||
| 34 | } | - | ||||||
| 35 | - | |||||||
| 36 | /* | - | ||||||
| 37 | * BN_mod_add variant that may be used if both a and b are non-negative and | - | ||||||
| 38 | * less than m. The original algorithm was | - | ||||||
| 39 | * | - | ||||||
| 40 | * if (!BN_uadd(r, a, b)) | - | ||||||
| 41 | * return 0; | - | ||||||
| 42 | * if (BN_ucmp(r, m) >= 0) | - | ||||||
| 43 | * return BN_usub(r, r, m); | - | ||||||
| 44 | * | - | ||||||
| 45 | * which is replaced with addition, subtracting modulus, and conditional | - | ||||||
| 46 | * move depending on whether or not subtraction borrowed. | - | ||||||
| 47 | */ | - | ||||||
| 48 | int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | - | ||||||
| 49 | const BIGNUM *m) | - | ||||||
| 50 | { | - | ||||||
| 51 | size_t i, ai, bi, mtop = m->top; | - | ||||||
| 52 | BN_ULONG storage[1024 / BN_BITS2]; | - | ||||||
| 53 | BN_ULONG carry, temp, mask, *rp, *tp = storage; | - | ||||||
| 54 | const BN_ULONG *ap, *bp; | - | ||||||
| 55 | - | |||||||
| 56 |     if (bn_wexpand(r, mtop) == NULL)
  | 0-4337421 | ||||||
| 57 |         return 0; never executed:  return 0; | 0 | ||||||
| 58 | - | |||||||
| 59 |     if (mtop > sizeof(storage) / sizeof(storage[0])
  | 1868-4335553 | ||||||
| 60 |         && (tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))) == NULL)
  | 0-1868 | ||||||
| 61 |         return 0; never executed:  return 0; | 0 | ||||||
| 62 | - | |||||||
| 63 |     ap = a->d != NULL ? a->d : tp;
  | 0-4337421 | ||||||
| 64 |     bp = b->d != NULL ? b->d : tp;
  | 298-4337123 | ||||||
| 65 | - | |||||||
| 66 |     for (i = 0, ai = 0, bi = 0, carry = 0; i < mtop;) {
  | 4337421-27221631 | ||||||
| 67 | mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); | - | ||||||
| 68 | temp = ((ap[ai] & mask) + carry) & BN_MASK2; | - | ||||||
| 69 | carry = (temp < carry); | - | ||||||
| 70 | - | |||||||
| 71 | mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); | - | ||||||
| 72 | tp[i] = ((bp[bi] & mask) + temp) & BN_MASK2; | - | ||||||
| 73 | carry += (tp[i] < temp); | - | ||||||
| 74 | - | |||||||
| 75 | i++; | - | ||||||
| 76 | ai += (i - a->dmax) >> (8 * sizeof(i) - 1); | - | ||||||
| 77 | bi += (i - b->dmax) >> (8 * sizeof(i) - 1); | - | ||||||
| 78 |     } executed 27221631 times by 2 tests:  end of blockExecuted by: 
  | 27221631 | ||||||
| 79 | rp = r->d; | - | ||||||
| 80 | carry -= bn_sub_words(rp, tp, m->d, mtop); | - | ||||||
| 81 |     for (i = 0; i < mtop; i++) {
  | 4337421-27221631 | ||||||
| 82 | rp[i] = (carry & tp[i]) | (~carry & rp[i]); | - | ||||||
| 83 | ((volatile BN_ULONG *)tp)[i] = 0; | - | ||||||
| 84 |     } executed 27221631 times by 2 tests:  end of blockExecuted by: 
  | 27221631 | ||||||
| 85 | r->top = mtop; | - | ||||||
| 86 | r->flags |= BN_FLG_FIXED_TOP; | - | ||||||
| 87 | r->neg = 0; | - | ||||||
| 88 | - | |||||||
| 89 |     if (tp != storage)
  | 1868-4335553 | ||||||
| 90 |         OPENSSL_free(tp); executed 1868 times by 1 test:  CRYPTO_free(tp, __FILE__, 90);Executed by: 
  | 1868 | ||||||
| 91 | - | |||||||
| 92 |     return 1; executed 4337421 times by 2 tests:  return 1;Executed by: 
  | 4337421 | ||||||
| 93 | } | - | ||||||
| 94 | - | |||||||
| 95 | int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | - | ||||||
| 96 | const BIGNUM *m) | - | ||||||
| 97 | { | - | ||||||
| 98 | int ret = bn_mod_add_fixed_top(r, a, b, m); | - | ||||||
| 99 | - | |||||||
| 100 |     if (ret)
  | 0-4334680 | ||||||
| 101 |         bn_correct_top(r); executed 4334680 times by 2 tests:  bn_correct_top(r);Executed by: 
  | 4334680 | ||||||
| 102 | - | |||||||
| 103 |     return ret; executed 4334680 times by 2 tests:  return ret;Executed by: 
  | 4334680 | ||||||
| 104 | } | - | ||||||
| 105 | - | |||||||
| 106 | int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, | - | ||||||
| 107 | BN_CTX *ctx) | - | ||||||
| 108 | { | - | ||||||
| 109 |     if (!BN_sub(r, a, b))
  | 0-13 | ||||||
| 110 |         return 0; never executed:  return 0; | 0 | ||||||
| 111 |     return BN_nnmod(r, r, m, ctx); executed 13 times by 1 test:  return BN_nnmod(r, r, m, ctx);Executed by: 
  | 13 | ||||||
| 112 | } | - | ||||||
| 113 | - | |||||||
| 114 | /* | - | ||||||
| 115 | * BN_mod_sub variant that may be used if both a and b are non-negative, | - | ||||||
| 116 | * a is less than m, while b is of same bit width as m. It's implemented | - | ||||||
| 117 | * as subtraction followed by two conditional additions. | - | ||||||
| 118 | * | - | ||||||
| 119 | * 0 <= a < m | - | ||||||
| 120 | * 0 <= b < 2^w < 2*m | - | ||||||
| 121 | * | - | ||||||
| 122 | * after subtraction | - | ||||||
| 123 | * | - | ||||||
| 124 | * -2*m < r = a - b < m | - | ||||||
| 125 | * | - | ||||||
| 126 | * Thus it takes up to two conditional additions to make |r| positive. | - | ||||||
| 127 | */ | - | ||||||
| 128 | int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | - | ||||||
| 129 | const BIGNUM *m) | - | ||||||
| 130 | { | - | ||||||
| 131 | size_t i, ai, bi, mtop = m->top; | - | ||||||
| 132 | BN_ULONG borrow, carry, ta, tb, mask, *rp; | - | ||||||
| 133 | const BN_ULONG *ap, *bp; | - | ||||||
| 134 | - | |||||||
| 135 |     if (bn_wexpand(r, mtop) == NULL)
  | 0-2374 | ||||||
| 136 |         return 0; never executed:  return 0; | 0 | ||||||
| 137 | - | |||||||
| 138 | rp = r->d; | - | ||||||
| 139 |     ap = a->d != NULL ? a->d : rp;
  | 0-2374 | ||||||
| 140 |     bp = b->d != NULL ? b->d : rp;
  | 0-2374 | ||||||
| 141 | - | |||||||
| 142 |     for (i = 0, ai = 0, bi = 0, borrow = 0; i < mtop;) {
  | 2374-32678 | ||||||
| 143 | mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); | - | ||||||
| 144 | ta = ap[ai] & mask; | - | ||||||
| 145 | - | |||||||
| 146 | mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); | - | ||||||
| 147 | tb = bp[bi] & mask; | - | ||||||
| 148 | rp[i] = ta - tb - borrow; | - | ||||||
| 149 |         if (ta != tb)
  | 43-32635 | ||||||
| 150 |             borrow = (ta < tb); executed 32635 times by 1 test:  borrow = (ta < tb);Executed by: 
  | 32635 | ||||||
| 151 | - | |||||||
| 152 | i++; | - | ||||||
| 153 | ai += (i - a->dmax) >> (8 * sizeof(i) - 1); | - | ||||||
| 154 | bi += (i - b->dmax) >> (8 * sizeof(i) - 1); | - | ||||||
| 155 |     } executed 32678 times by 1 test:  end of blockExecuted by: 
  | 32678 | ||||||
| 156 | ap = m->d; | - | ||||||
| 157 |     for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) {
  | 2374-32678 | ||||||
| 158 | ta = ((ap[i] & mask) + carry) & BN_MASK2; | - | ||||||
| 159 | carry = (ta < carry); | - | ||||||
| 160 | rp[i] = (rp[i] + ta) & BN_MASK2; | - | ||||||
| 161 | carry += (rp[i] < ta); | - | ||||||
| 162 |     } executed 32678 times by 1 test:  end of blockExecuted by: 
  | 32678 | ||||||
| 163 | borrow -= carry; | - | ||||||
| 164 |     for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) {
  | 2374-32678 | ||||||
| 165 | ta = ((ap[i] & mask) + carry) & BN_MASK2; | - | ||||||
| 166 | carry = (ta < carry); | - | ||||||
| 167 | rp[i] = (rp[i] + ta) & BN_MASK2; | - | ||||||
| 168 | carry += (rp[i] < ta); | - | ||||||
| 169 |     } executed 32678 times by 1 test:  end of blockExecuted by: 
  | 32678 | ||||||
| 170 | - | |||||||
| 171 | r->top = mtop; | - | ||||||
| 172 | r->flags |= BN_FLG_FIXED_TOP; | - | ||||||
| 173 | r->neg = 0; | - | ||||||
| 174 | - | |||||||
| 175 |     return 1; executed 2374 times by 1 test:  return 1;Executed by: 
  | 2374 | ||||||
| 176 | } | - | ||||||
| 177 | - | |||||||
| 178 | /* | - | ||||||
| 179 | * BN_mod_sub variant that may be used if both a and b are non-negative and | - | ||||||
| 180 | * less than m | - | ||||||
| 181 | */ | - | ||||||
| 182 | int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | - | ||||||
| 183 | const BIGNUM *m) | - | ||||||
| 184 | { | - | ||||||
| 185 |     if (!BN_sub(r, a, b))
  | 0-4650717 | ||||||
| 186 |         return 0; never executed:  return 0; | 0 | ||||||
| 187 |     if (r->neg)
  | 2309212-2341505 | ||||||
| 188 |         return BN_add(r, r, m); executed 2309212 times by 2 tests:  return BN_add(r, r, m);Executed by: 
  | 2309212 | ||||||
| 189 |     return 1; executed 2341505 times by 2 tests:  return 1;Executed by: 
  | 2341505 | ||||||
| 190 | } | - | ||||||
| 191 | - | |||||||
| 192 | /* slow but works */ | - | ||||||
| 193 | int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, | - | ||||||
| 194 | BN_CTX *ctx) | - | ||||||
| 195 | { | - | ||||||
| 196 | BIGNUM *t; | - | ||||||
| 197 | int ret = 0; | - | ||||||
| 198 | - | |||||||
| 199 | bn_check_top(a); | - | ||||||
| 200 | bn_check_top(b); | - | ||||||
| 201 | bn_check_top(m); | - | ||||||
| 202 | - | |||||||
| 203 | BN_CTX_start(ctx); | - | ||||||
| 204 |     if ((t = BN_CTX_get(ctx)) == NULL)
  | 0-3791466 | ||||||
| 205 |         goto err; never executed:  goto err; | 0 | ||||||
| 206 |     if (a == b) {
  | 189583-3601883 | ||||||
| 207 |         if (!BN_sqr(t, a, ctx))
  | 0-3601883 | ||||||
| 208 |             goto err; never executed:  goto err; | 0 | ||||||
| 209 |     } else { executed 3601883 times by 1 test:  end of blockExecuted by: 
  | 3601883 | ||||||
| 210 |         if (!BN_mul(t, a, b, ctx))
  | 0-189583 | ||||||
| 211 |             goto err; never executed:  goto err; | 0 | ||||||
| 212 |     } executed 189583 times by 2 tests:  end of blockExecuted by: 
  | 189583 | ||||||
| 213 |     if (!BN_nnmod(r, t, m, ctx))
  | 1-3791465 | ||||||
| 214 |         goto err; executed 1 time by 1 test:  goto err;Executed by: 
  | 1 | ||||||
| 215 | bn_check_top(r); | - | ||||||
| 216 | ret = 1; | - | ||||||
| 217 |  err: code before this statement executed 3791465 times by 2 tests:  err:Executed by: 
  | 3791465 | ||||||
| 218 | BN_CTX_end(ctx); | - | ||||||
| 219 |     return ret; executed 3791466 times by 2 tests:  return ret;Executed by: 
  | 3791466 | ||||||
| 220 | } | - | ||||||
| 221 | - | |||||||
| 222 | int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) | - | ||||||
| 223 | { | - | ||||||
| 224 |     if (!BN_sqr(r, a, ctx))
  | 0-147879 | ||||||
| 225 |         return 0; never executed:  return 0; | 0 | ||||||
| 226 | /* r->neg == 0, thus we don't need BN_nnmod */ | - | ||||||
| 227 |     return BN_mod(r, r, m, ctx); executed 147879 times by 2 tests:  return BN_div( ((void *)0) ,(r),(r),(m),(ctx));Executed by: 
  | 147879 | ||||||
| 228 | } | - | ||||||
| 229 | - | |||||||
| 230 | int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) | - | ||||||
| 231 | { | - | ||||||
| 232 |     if (!BN_lshift1(r, a))
  | 0 | ||||||
| 233 |         return 0; never executed:  return 0; | 0 | ||||||
| 234 | bn_check_top(r); | - | ||||||
| 235 |     return BN_nnmod(r, r, m, ctx); never executed:  return BN_nnmod(r, r, m, ctx); | 0 | ||||||
| 236 | } | - | ||||||
| 237 | - | |||||||
| 238 | /* | - | ||||||
| 239 | * BN_mod_lshift1 variant that may be used if a is non-negative and less than | - | ||||||
| 240 | * m | - | ||||||
| 241 | */ | - | ||||||
| 242 | int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) | - | ||||||
| 243 | { | - | ||||||
| 244 |     if (!BN_lshift1(r, a))
  | 0-1775606 | ||||||
| 245 |         return 0; never executed:  return 0; | 0 | ||||||
| 246 | bn_check_top(r); | - | ||||||
| 247 |     if (BN_cmp(r, m) >= 0)
  | 883028-892578 | ||||||
| 248 |         return BN_sub(r, r, m); executed 892578 times by 2 tests:  return BN_sub(r, r, m);Executed by: 
  | 892578 | ||||||
| 249 |     return 1; executed 883028 times by 2 tests:  return 1;Executed by: 
  | 883028 | ||||||
| 250 | } | - | ||||||
| 251 | - | |||||||
| 252 | int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, | - | ||||||
| 253 | BN_CTX *ctx) | - | ||||||
| 254 | { | - | ||||||
| 255 | BIGNUM *abs_m = NULL; | - | ||||||
| 256 | int ret; | - | ||||||
| 257 | - | |||||||
| 258 |     if (!BN_nnmod(r, a, m, ctx))
  | 0 | ||||||
| 259 |         return 0; never executed:  return 0; | 0 | ||||||
| 260 | - | |||||||
| 261 |     if (m->neg) {
  | 0 | ||||||
| 262 | abs_m = BN_dup(m); | - | ||||||
| 263 |         if (abs_m == NULL)
  | 0 | ||||||
| 264 |             return 0; never executed:  return 0; | 0 | ||||||
| 265 | abs_m->neg = 0; | - | ||||||
| 266 |     } never executed:  end of block | 0 | ||||||
| 267 | - | |||||||
| 268 | ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m)); | - | ||||||
| 269 | bn_check_top(r); | - | ||||||
| 270 | - | |||||||
| 271 | BN_free(abs_m); | - | ||||||
| 272 |     return ret; never executed:  return ret; | 0 | ||||||
| 273 | } | - | ||||||
| 274 | - | |||||||
| 275 | /* | - | ||||||
| 276 | * BN_mod_lshift variant that may be used if a is non-negative and less than | - | ||||||
| 277 | * m | - | ||||||
| 278 | */ | - | ||||||
| 279 | int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) | - | ||||||
| 280 | { | - | ||||||
| 281 |     if (r != a) {
  | 151159-783904 | ||||||
| 282 |         if (BN_copy(r, a) == NULL)
  | 0-783904 | ||||||
| 283 |             return 0; never executed:  return 0; | 0 | ||||||
| 284 |     } executed 783904 times by 2 tests:  end of blockExecuted by: 
  | 783904 | ||||||
| 285 | - | |||||||
| 286 |     while (n > 0) {
  | 935063-1530937 | ||||||
| 287 | int max_shift; | - | ||||||
| 288 | - | |||||||
| 289 | /* 0 < r < m */ | - | ||||||
| 290 | max_shift = BN_num_bits(m) - BN_num_bits(r); | - | ||||||
| 291 | /* max_shift >= 0 */ | - | ||||||
| 292 | - | |||||||
| 293 |         if (max_shift < 0) {
  | 0-1530937 | ||||||
| 294 | BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED); | - | ||||||
| 295 |             return 0; never executed:  return 0; | 0 | ||||||
| 296 | } | - | ||||||
| 297 | - | |||||||
| 298 |         if (max_shift > n)
  | 185297-1345640 | ||||||
| 299 |             max_shift = n; executed 185297 times by 2 tests:  max_shift = n;Executed by: 
  | 185297 | ||||||
| 300 | - | |||||||
| 301 |         if (max_shift) {
  | 694555-836382 | ||||||
| 302 |             if (!BN_lshift(r, r, max_shift))
  | 0-836382 | ||||||
| 303 |                 return 0; never executed:  return 0; | 0 | ||||||
| 304 | n -= max_shift; | - | ||||||
| 305 |         } else { executed 836382 times by 2 tests:  end of blockExecuted by: 
  | 836382 | ||||||
| 306 |             if (!BN_lshift1(r, r))
  | 0-694555 | ||||||
| 307 |                 return 0; never executed:  return 0; | 0 | ||||||
| 308 | --n; | - | ||||||
| 309 |         } executed 694555 times by 2 tests:  end of blockExecuted by: 
  | 694555 | ||||||
| 310 | - | |||||||
| 311 | /* BN_num_bits(r) <= BN_num_bits(m) */ | - | ||||||
| 312 | - | |||||||
| 313 |         if (BN_cmp(r, m) >= 0) {
  | 730613-800324 | ||||||
| 314 |             if (!BN_sub(r, r, m))
  | 0-800324 | ||||||
| 315 |                 return 0; never executed:  return 0; | 0 | ||||||
| 316 |         } executed 800324 times by 2 tests:  end of blockExecuted by: 
  | 800324 | ||||||
| 317 |     } executed 1530937 times by 2 tests:  end of blockExecuted by: 
  | 1530937 | ||||||
| 318 | bn_check_top(r); | - | ||||||
| 319 | - | |||||||
| 320 |     return 1; executed 935063 times by 2 tests:  return 1;Executed by: 
  | 935063 | ||||||
| 321 | } | - | ||||||
| Source code | Switch to Preprocessed file |