/src/openssl30/crypto/bn/bn_shift.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 <assert.h> | 
| 11 |  | #include "internal/cryptlib.h" | 
| 12 |  | #include "bn_local.h" | 
| 13 |  |  | 
| 14 |  | int BN_lshift1(BIGNUM *r, const BIGNUM *a) | 
| 15 | 3.74M | { | 
| 16 | 3.74M |     register BN_ULONG *ap, *rp, t, c; | 
| 17 | 3.74M |     int i; | 
| 18 |  |  | 
| 19 | 3.74M |     bn_check_top(r); | 
| 20 | 3.74M |     bn_check_top(a); | 
| 21 |  |  | 
| 22 | 3.74M |     if (r != a) { | 
| 23 | 1.01M |         r->neg = a->neg; | 
| 24 | 1.01M |         if (bn_wexpand(r, a->top + 1) == NULL) | 
| 25 | 0 |             return 0; | 
| 26 | 1.01M |         r->top = a->top; | 
| 27 | 2.73M |     } else { | 
| 28 | 2.73M |         if (bn_wexpand(r, a->top + 1) == NULL) | 
| 29 | 0 |             return 0; | 
| 30 | 2.73M |     } | 
| 31 | 3.74M |     ap = a->d; | 
| 32 | 3.74M |     rp = r->d; | 
| 33 | 3.74M |     c = 0; | 
| 34 | 20.3M |     for (i = 0; i < a->top; i++) { | 
| 35 | 16.5M |         t = *(ap++); | 
| 36 | 16.5M |         *(rp++) = ((t << 1) | c) & BN_MASK2; | 
| 37 | 16.5M |         c = t >> (BN_BITS2 - 1); | 
| 38 | 16.5M |     } | 
| 39 | 3.74M |     *rp = c; | 
| 40 | 3.74M |     r->top += c; | 
| 41 | 3.74M |     bn_check_top(r); | 
| 42 | 3.74M |     return 1; | 
| 43 | 3.74M | } | 
| 44 |  |  | 
| 45 |  | int BN_rshift1(BIGNUM *r, const BIGNUM *a) | 
| 46 | 50.8M | { | 
| 47 | 50.8M |     BN_ULONG *ap, *rp, t, c; | 
| 48 | 50.8M |     int i; | 
| 49 |  |  | 
| 50 | 50.8M |     bn_check_top(r); | 
| 51 | 50.8M |     bn_check_top(a); | 
| 52 |  |  | 
| 53 | 50.8M |     if (BN_is_zero(a)) { | 
| 54 | 7.01M |         BN_zero(r); | 
| 55 | 7.01M |         return 1; | 
| 56 | 7.01M |     } | 
| 57 | 43.7M |     i = a->top; | 
| 58 | 43.7M |     ap = a->d; | 
| 59 | 43.7M |     if (a != r) { | 
| 60 | 81.5k |         if (bn_wexpand(r, i) == NULL) | 
| 61 | 0 |             return 0; | 
| 62 | 81.5k |         r->neg = a->neg; | 
| 63 | 81.5k |     } | 
| 64 | 43.7M |     rp = r->d; | 
| 65 | 43.7M |     r->top = i; | 
| 66 | 43.7M |     t = ap[--i]; | 
| 67 | 43.7M |     rp[i] = t >> 1; | 
| 68 | 43.7M |     c = t << (BN_BITS2 - 1); | 
| 69 | 43.7M |     r->top -= (t == 1); | 
| 70 | 3.80G |     while (i > 0) { | 
| 71 | 3.75G |         t = ap[--i]; | 
| 72 | 3.75G |         rp[i] = ((t >> 1) & BN_MASK2) | c; | 
| 73 | 3.75G |         c = t << (BN_BITS2 - 1); | 
| 74 | 3.75G |     } | 
| 75 | 43.7M |     if (!r->top) | 
| 76 | 16 |         r->neg = 0; /* don't allow negative zero */ | 
| 77 | 43.7M |     bn_check_top(r); | 
| 78 | 43.7M |     return 1; | 
| 79 | 43.7M | } | 
| 80 |  |  | 
| 81 |  | int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) | 
| 82 | 4.38M | { | 
| 83 | 4.38M |     int ret; | 
| 84 |  |  | 
| 85 | 4.38M |     if (n < 0) { | 
| 86 | 0 |         ERR_raise(ERR_LIB_BN, BN_R_INVALID_SHIFT); | 
| 87 | 0 |         return 0; | 
| 88 | 0 |     } | 
| 89 |  |  | 
| 90 | 4.38M |     ret = bn_lshift_fixed_top(r, a, n); | 
| 91 |  |  | 
| 92 | 4.38M |     bn_correct_top(r); | 
| 93 | 4.38M |     bn_check_top(r); | 
| 94 |  |  | 
| 95 | 4.38M |     return ret; | 
| 96 | 4.38M | } | 
| 97 |  |  | 
| 98 |  | /* | 
| 99 |  |  * In respect to shift factor the execution time is invariant of | 
| 100 |  |  * |n % BN_BITS2|, but not |n / BN_BITS2|. Or in other words pre-condition | 
| 101 |  |  * for constant-time-ness is |n < BN_BITS2| or |n / BN_BITS2| being | 
| 102 |  |  * non-secret. | 
| 103 |  |  */ | 
| 104 |  | int bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n) | 
| 105 | 68.3M | { | 
| 106 | 68.3M |     int i, nw; | 
| 107 | 68.3M |     unsigned int lb, rb; | 
| 108 | 68.3M |     BN_ULONG *t, *f; | 
| 109 | 68.3M |     BN_ULONG l, m, rmask = 0; | 
| 110 |  |  | 
| 111 | 68.3M |     assert(n >= 0); | 
| 112 |  |  | 
| 113 | 68.3M |     bn_check_top(r); | 
| 114 | 68.3M |     bn_check_top(a); | 
| 115 |  |  | 
| 116 | 68.3M |     nw = n / BN_BITS2; | 
| 117 | 68.3M |     if (bn_wexpand(r, a->top + nw + 1) == NULL) | 
| 118 | 0 |         return 0; | 
| 119 |  |  | 
| 120 | 68.3M |     if (a->top != 0) { | 
| 121 | 68.1M |         lb = (unsigned int)n % BN_BITS2; | 
| 122 | 68.1M |         rb = BN_BITS2 - lb; | 
| 123 | 68.1M |         rb %= BN_BITS2;            /* say no to undefined behaviour */ | 
| 124 | 68.1M |         rmask = (BN_ULONG)0 - rb;  /* rmask = 0 - (rb != 0) */ | 
| 125 | 68.1M |         rmask |= rmask >> 8; | 
| 126 | 68.1M |         f = &(a->d[0]); | 
| 127 | 68.1M |         t = &(r->d[nw]); | 
| 128 | 68.1M |         l = f[a->top - 1]; | 
| 129 | 68.1M |         t[a->top] = (l >> rb) & rmask; | 
| 130 | 636M |         for (i = a->top - 1; i > 0; i--) { | 
| 131 | 568M |             m = l << lb; | 
| 132 | 568M |             l = f[i - 1]; | 
| 133 | 568M |             t[i] = (m | ((l >> rb) & rmask)) & BN_MASK2; | 
| 134 | 568M |         } | 
| 135 | 68.1M |         t[0] = (l << lb) & BN_MASK2; | 
| 136 | 68.1M |     } else { | 
| 137 |  |         /* shouldn't happen, but formally required */ | 
| 138 | 292k |         r->d[nw] = 0; | 
| 139 | 292k |     } | 
| 140 | 68.3M |     if (nw != 0) | 
| 141 | 521k |         memset(r->d, 0, sizeof(*t) * nw); | 
| 142 |  |  | 
| 143 | 68.3M |     r->neg = a->neg; | 
| 144 | 68.3M |     r->top = a->top + nw + 1; | 
| 145 | 68.3M |     r->flags |= BN_FLG_FIXED_TOP; | 
| 146 |  |  | 
| 147 | 68.3M |     return 1; | 
| 148 | 68.3M | } | 
| 149 |  |  | 
| 150 |  | int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) | 
| 151 | 37.4M | { | 
| 152 | 37.4M |     int ret = 0; | 
| 153 |  |  | 
| 154 | 37.4M |     if (n < 0) { | 
| 155 | 0 |         ERR_raise(ERR_LIB_BN, BN_R_INVALID_SHIFT); | 
| 156 | 0 |         return 0; | 
| 157 | 0 |     } | 
| 158 |  |  | 
| 159 | 37.4M |     ret = bn_rshift_fixed_top(r, a, n); | 
| 160 |  |  | 
| 161 | 37.4M |     bn_correct_top(r); | 
| 162 | 37.4M |     bn_check_top(r); | 
| 163 |  |  | 
| 164 | 37.4M |     return ret; | 
| 165 | 37.4M | } | 
| 166 |  |  | 
| 167 |  | /* | 
| 168 |  |  * In respect to shift factor the execution time is invariant of | 
| 169 |  |  * |n % BN_BITS2|, but not |n / BN_BITS2|. Or in other words pre-condition | 
| 170 |  |  * for constant-time-ness for sufficiently[!] zero-padded inputs is | 
| 171 |  |  * |n < BN_BITS2| or |n / BN_BITS2| being non-secret. | 
| 172 |  |  */ | 
| 173 |  | int bn_rshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n) | 
| 174 | 100M | { | 
| 175 | 100M |     int i, top, nw; | 
| 176 | 100M |     unsigned int lb, rb; | 
| 177 | 100M |     BN_ULONG *t, *f; | 
| 178 | 100M |     BN_ULONG l, m, mask; | 
| 179 |  |  | 
| 180 | 100M |     bn_check_top(r); | 
| 181 | 100M |     bn_check_top(a); | 
| 182 |  |  | 
| 183 | 100M |     assert(n >= 0); | 
| 184 |  |  | 
| 185 | 100M |     nw = n / BN_BITS2; | 
| 186 | 100M |     if (nw >= a->top) { | 
| 187 |  |         /* shouldn't happen, but formally required */ | 
| 188 | 4.37k |         BN_zero(r); | 
| 189 | 4.37k |         return 1; | 
| 190 | 4.37k |     } | 
| 191 |  |  | 
| 192 | 100M |     rb = (unsigned int)n % BN_BITS2; | 
| 193 | 100M |     lb = BN_BITS2 - rb; | 
| 194 | 100M |     lb %= BN_BITS2;            /* say no to undefined behaviour */ | 
| 195 | 100M |     mask = (BN_ULONG)0 - lb;   /* mask = 0 - (lb != 0) */ | 
| 196 | 100M |     mask |= mask >> 8; | 
| 197 | 100M |     top = a->top - nw; | 
| 198 | 100M |     if (r != a && bn_wexpand(r, top) == NULL) | 
| 199 | 0 |         return 0; | 
| 200 |  |  | 
| 201 | 100M |     t = &(r->d[0]); | 
| 202 | 100M |     f = &(a->d[nw]); | 
| 203 | 100M |     l = f[0]; | 
| 204 | 527M |     for (i = 0; i < top - 1; i++) { | 
| 205 | 426M |         m = f[i + 1]; | 
| 206 | 426M |         t[i] = (l >> rb) | ((m << lb) & mask); | 
| 207 | 426M |         l = m; | 
| 208 | 426M |     } | 
| 209 | 100M |     t[i] = l >> rb; | 
| 210 |  |  | 
| 211 | 100M |     r->neg = a->neg; | 
| 212 | 100M |     r->top = top; | 
| 213 | 100M |     r->flags |= BN_FLG_FIXED_TOP; | 
| 214 |  |  | 
| 215 | 100M |     return 1; | 
| 216 | 100M | } |