/src/openssl30/crypto/bn/bn_add.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. | 
| 3 |  |  * | 
| 4 |  |  * Licensed under the Apache License 2.0 (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_local.h" | 
| 12 |  |  | 
| 13 |  | /* signed add of b to a. */ | 
| 14 |  | int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | 
| 15 | 32.1M | { | 
| 16 | 32.1M |     int ret, r_neg, cmp_res; | 
| 17 |  |  | 
| 18 | 32.1M |     bn_check_top(a); | 
| 19 | 32.1M |     bn_check_top(b); | 
| 20 |  |  | 
| 21 | 32.1M |     if (a->neg == b->neg) { | 
| 22 | 17.0M |         r_neg = a->neg; | 
| 23 | 17.0M |         ret = BN_uadd(r, a, b); | 
| 24 | 17.0M |     } else { | 
| 25 | 15.1M |         cmp_res = BN_ucmp(a, b); | 
| 26 | 15.1M |         if (cmp_res > 0) { | 
| 27 | 4.90M |             r_neg = a->neg; | 
| 28 | 4.90M |             ret = BN_usub(r, a, b); | 
| 29 | 10.2M |         } else if (cmp_res < 0) { | 
| 30 | 10.2M |             r_neg = b->neg; | 
| 31 | 10.2M |             ret = BN_usub(r, b, a); | 
| 32 | 10.2M |         } else { | 
| 33 | 3.66k |             r_neg = 0; | 
| 34 | 3.66k |             BN_zero(r); | 
| 35 | 3.66k |             ret = 1; | 
| 36 | 3.66k |         } | 
| 37 | 15.1M |     } | 
| 38 |  |  | 
| 39 | 32.1M |     r->neg = r_neg; | 
| 40 | 32.1M |     bn_check_top(r); | 
| 41 | 32.1M |     return ret; | 
| 42 | 32.1M | } | 
| 43 |  |  | 
| 44 |  | /* signed sub of b from a. */ | 
| 45 |  | int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | 
| 46 | 8.89M | { | 
| 47 | 8.89M |     int ret, r_neg, cmp_res; | 
| 48 |  |  | 
| 49 | 8.89M |     bn_check_top(a); | 
| 50 | 8.89M |     bn_check_top(b); | 
| 51 |  |  | 
| 52 | 8.89M |     if (a->neg != b->neg) { | 
| 53 | 0 |         r_neg = a->neg; | 
| 54 | 0 |         ret = BN_uadd(r, a, b); | 
| 55 | 8.89M |     } else { | 
| 56 | 8.89M |         cmp_res = BN_ucmp(a, b); | 
| 57 | 8.89M |         if (cmp_res > 0) { | 
| 58 | 5.79M |             r_neg = a->neg; | 
| 59 | 5.79M |             ret = BN_usub(r, a, b); | 
| 60 | 5.79M |         } else if (cmp_res < 0) { | 
| 61 | 3.08M |             r_neg = !b->neg; | 
| 62 | 3.08M |             ret = BN_usub(r, b, a); | 
| 63 | 3.08M |         } else { | 
| 64 | 13.0k |             r_neg = 0; | 
| 65 | 13.0k |             BN_zero(r); | 
| 66 | 13.0k |             ret = 1; | 
| 67 | 13.0k |         } | 
| 68 | 8.89M |     } | 
| 69 |  |  | 
| 70 | 8.89M |     r->neg = r_neg; | 
| 71 | 8.89M |     bn_check_top(r); | 
| 72 | 8.89M |     return ret; | 
| 73 | 8.89M | } | 
| 74 |  |  | 
| 75 |  | /* unsigned add of b to a, r can be equal to a or b. */ | 
| 76 |  | int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | 
| 77 | 61.1M | { | 
| 78 | 61.1M |     int max, min, dif; | 
| 79 | 61.1M |     const BN_ULONG *ap, *bp; | 
| 80 | 61.1M |     BN_ULONG *rp, carry, t1, t2; | 
| 81 |  |  | 
| 82 | 61.1M |     bn_check_top(a); | 
| 83 | 61.1M |     bn_check_top(b); | 
| 84 |  |  | 
| 85 | 61.1M |     if (a->top < b->top) { | 
| 86 | 4.15M |         const BIGNUM *tmp; | 
| 87 |  |  | 
| 88 | 4.15M |         tmp = a; | 
| 89 | 4.15M |         a = b; | 
| 90 | 4.15M |         b = tmp; | 
| 91 | 4.15M |     } | 
| 92 | 61.1M |     max = a->top; | 
| 93 | 61.1M |     min = b->top; | 
| 94 | 61.1M |     dif = max - min; | 
| 95 |  |  | 
| 96 | 61.1M |     if (bn_wexpand(r, max + 1) == NULL) | 
| 97 | 0 |         return 0; | 
| 98 |  |  | 
| 99 | 61.1M |     r->top = max; | 
| 100 |  |  | 
| 101 | 61.1M |     ap = a->d; | 
| 102 | 61.1M |     bp = b->d; | 
| 103 | 61.1M |     rp = r->d; | 
| 104 |  |  | 
| 105 | 61.1M |     carry = bn_add_words(rp, ap, bp, min); | 
| 106 | 61.1M |     rp += min; | 
| 107 | 61.1M |     ap += min; | 
| 108 |  |  | 
| 109 | 174M |     while (dif) { | 
| 110 | 113M |         dif--; | 
| 111 | 113M |         t1 = *(ap++); | 
| 112 | 113M |         t2 = (t1 + carry) & BN_MASK2; | 
| 113 | 113M |         *(rp++) = t2; | 
| 114 | 113M |         carry &= (t2 == 0); | 
| 115 | 113M |     } | 
| 116 | 61.1M |     *rp = carry; | 
| 117 | 61.1M |     r->top += carry; | 
| 118 |  |  | 
| 119 | 61.1M |     r->neg = 0; | 
| 120 | 61.1M |     bn_check_top(r); | 
| 121 | 61.1M |     return 1; | 
| 122 | 61.1M | } | 
| 123 |  |  | 
| 124 |  | /* unsigned subtraction of b from a, a must be larger than b. */ | 
| 125 |  | int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | 
| 126 | 56.9M | { | 
| 127 | 56.9M |     int max, min, dif; | 
| 128 | 56.9M |     BN_ULONG t1, t2, borrow, *rp; | 
| 129 | 56.9M |     const BN_ULONG *ap, *bp; | 
| 130 |  |  | 
| 131 | 56.9M |     bn_check_top(a); | 
| 132 | 56.9M |     bn_check_top(b); | 
| 133 |  |  | 
| 134 | 56.9M |     max = a->top; | 
| 135 | 56.9M |     min = b->top; | 
| 136 | 56.9M |     dif = max - min; | 
| 137 |  |  | 
| 138 | 56.9M |     if (dif < 0) {              /* hmm... should not be happening */ | 
| 139 | 0 |         ERR_raise(ERR_LIB_BN, BN_R_ARG2_LT_ARG3); | 
| 140 | 0 |         return 0; | 
| 141 | 0 |     } | 
| 142 |  |  | 
| 143 | 56.9M |     if (bn_wexpand(r, max) == NULL) | 
| 144 | 0 |         return 0; | 
| 145 |  |  | 
| 146 | 56.9M |     ap = a->d; | 
| 147 | 56.9M |     bp = b->d; | 
| 148 | 56.9M |     rp = r->d; | 
| 149 |  |  | 
| 150 | 56.9M |     borrow = bn_sub_words(rp, ap, bp, min); | 
| 151 | 56.9M |     ap += min; | 
| 152 | 56.9M |     rp += min; | 
| 153 |  |  | 
| 154 | 163M |     while (dif) { | 
| 155 | 106M |         dif--; | 
| 156 | 106M |         t1 = *(ap++); | 
| 157 | 106M |         t2 = (t1 - borrow) & BN_MASK2; | 
| 158 | 106M |         *(rp++) = t2; | 
| 159 | 106M |         borrow &= (t1 == 0); | 
| 160 | 106M |     } | 
| 161 |  |  | 
| 162 | 71.9M |     while (max && *--rp == 0) | 
| 163 | 15.0M |         max--; | 
| 164 |  |  | 
| 165 | 56.9M |     r->top = max; | 
| 166 | 56.9M |     r->neg = 0; | 
| 167 | 56.9M |     bn_pollute(r); | 
| 168 |  |  | 
| 169 | 56.9M |     return 1; | 
| 170 | 56.9M | } | 
| 171 |  |  |