summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/bn/bn_shift.c83
1 files changed, 57 insertions, 26 deletions
diff --git a/src/lib/libcrypto/bn/bn_shift.c b/src/lib/libcrypto/bn/bn_shift.c
index 09f1c738ad..4b9a133b13 100644
--- a/src/lib/libcrypto/bn/bn_shift.c
+++ b/src/lib/libcrypto/bn/bn_shift.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_shift.c,v 1.18 2023/01/05 04:51:13 jsing Exp $ */ 1/* $OpenBSD: bn_shift.c,v 1.19 2023/01/10 04:13:22 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -130,40 +130,71 @@ BN_rshift1(BIGNUM *r, const BIGNUM *a)
130int 130int
131BN_lshift(BIGNUM *r, const BIGNUM *a, int n) 131BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
132{ 132{
133 int i, nw, lb, rb; 133 size_t count, shift_bits, shift_words;
134 BN_ULONG *t, *f; 134 size_t lshift, rshift;
135 BN_ULONG l; 135 ssize_t rstride;
136 BN_ULONG *dst, *src;
136 137
137 if (n < 0) { 138 if (n < 0) {
138 BNerror(BN_R_INVALID_LENGTH); 139 BNerror(BN_R_INVALID_LENGTH);
139 return 0; 140 return 0;
140 } 141 }
142 shift_bits = n;
143
144 /*
145 * Left bit shift, potentially across word boundaries.
146 *
147 * When shift is not an exact multiple of BN_BITS2, the bottom bits of
148 * the previous word need to be right shifted and combined with the left
149 * shifted bits using bitwise OR. If shift is an exact multiple of
150 * BN_BITS2, the source for the left and right shifts are the same
151 * and the shifts become zero bits (which is effectively a memmove).
152 */
153 shift_words = shift_bits / BN_BITS2;
154 lshift = shift_bits % BN_BITS2;
155 rshift = (BN_BITS2 - lshift) % BN_BITS2;
156 rstride = 0 - (lshift + rshift) / BN_BITS2;
157
158 if (a->top < 1) {
159 BN_zero(r);
160 return 1;
161 }
141 162
163 count = a->top + shift_words + 1;
142 164
165 if (count < shift_words)
166 return 0;
167
168 if (!bn_wexpand(r, count))
169 return 0;
170
171 src = a->d + a->top - 1;
172 dst = r->d + a->top + shift_words;
173
174 /* Handle right shift for top most word. */
175 *dst = (*src >> rshift) & rstride;
176 dst--;
177
178 /* Handle left shift and right shift for remaining words. */
179 while (src > a->d) {
180 *dst = *src << lshift | src[rstride] >> rshift;
181 src--;
182 dst--;
183 }
184 *dst = *src << lshift;
185
186 /* Zero any additional words resulting from the left shift. */
187 while (dst > r->d) {
188 dst--;
189 *dst = 0;
190 }
191
192 r->top = count;
143 r->neg = a->neg; 193 r->neg = a->neg;
144 nw = n / BN_BITS2; 194
145 if (!bn_wexpand(r, a->top + nw + 1))
146 return (0);
147 lb = n % BN_BITS2;
148 rb = BN_BITS2 - lb;
149 f = a->d;
150 t = r->d;
151 t[a->top + nw] = 0;
152 if (lb == 0)
153 for (i = a->top - 1; i >= 0; i--)
154 t[nw + i] = f[i];
155 else
156 for (i = a->top - 1; i >= 0; i--) {
157 l = f[i];
158 t[nw + i + 1] |= (l >> rb) & BN_MASK2;
159 t[nw + i] = (l << lb) & BN_MASK2;
160 }
161 memset(t, 0, nw * sizeof(t[0]));
162/* for (i=0; i<nw; i++)
163 t[i]=0;*/
164 r->top = a->top + nw + 1;
165 bn_correct_top(r); 195 bn_correct_top(r);
166 return (1); 196
197 return 1;
167} 198}
168 199
169int 200int