diff options
-rw-r--r-- | src/lib/libcrypto/bn/bn_add.c | 140 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_internal.h | 59 |
2 files changed, 88 insertions, 111 deletions
diff --git a/src/lib/libcrypto/bn/bn_add.c b/src/lib/libcrypto/bn/bn_add.c index 8ae9bbe854..51b87104cf 100644 --- a/src/lib/libcrypto/bn/bn_add.c +++ b/src/lib/libcrypto/bn/bn_add.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_add.c,v 1.22 2023/02/13 04:25:37 jsing Exp $ */ | 1 | /* $OpenBSD: bn_add.c,v 1.23 2023/02/16 04:42:20 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 | * |
@@ -64,89 +64,31 @@ | |||
64 | 64 | ||
65 | #include "bn_arch.h" | 65 | #include "bn_arch.h" |
66 | #include "bn_local.h" | 66 | #include "bn_local.h" |
67 | #include "bn_internal.h" | ||
67 | 68 | ||
68 | BN_ULONG bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b); | 69 | BN_ULONG bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b); |
69 | BN_ULONG bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b); | 70 | BN_ULONG bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b); |
70 | 71 | ||
72 | /* | ||
73 | * bn_add_words() computes (carry:r[i]) = a[i] + b[i] + carry, where a and b | ||
74 | * are both arrays of words. Any carry resulting from the addition is returned. | ||
75 | */ | ||
71 | #ifndef HAVE_BN_ADD_WORDS | 76 | #ifndef HAVE_BN_ADD_WORDS |
72 | #ifdef BN_LLONG | ||
73 | BN_ULONG | 77 | BN_ULONG |
74 | bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | 78 | bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) |
75 | { | 79 | { |
76 | BN_ULLONG ll = 0; | 80 | BN_ULONG carry = 0; |
77 | 81 | ||
78 | assert(n >= 0); | 82 | assert(n >= 0); |
79 | if (n <= 0) | 83 | if (n <= 0) |
80 | return ((BN_ULONG)0); | 84 | return 0; |
81 | |||
82 | #ifndef OPENSSL_SMALL_FOOTPRINT | ||
83 | while (n & ~3) { | ||
84 | ll += (BN_ULLONG)a[0] + b[0]; | ||
85 | r[0] = (BN_ULONG)ll & BN_MASK2; | ||
86 | ll >>= BN_BITS2; | ||
87 | ll += (BN_ULLONG)a[1] + b[1]; | ||
88 | r[1] = (BN_ULONG)ll & BN_MASK2; | ||
89 | ll >>= BN_BITS2; | ||
90 | ll += (BN_ULLONG)a[2] + b[2]; | ||
91 | r[2] = (BN_ULONG)ll & BN_MASK2; | ||
92 | ll >>= BN_BITS2; | ||
93 | ll += (BN_ULLONG)a[3] + b[3]; | ||
94 | r[3] = (BN_ULONG)ll & BN_MASK2; | ||
95 | ll >>= BN_BITS2; | ||
96 | a += 4; | ||
97 | b += 4; | ||
98 | r += 4; | ||
99 | n -= 4; | ||
100 | } | ||
101 | #endif | ||
102 | while (n) { | ||
103 | ll += (BN_ULLONG)a[0] + b[0]; | ||
104 | r[0] = (BN_ULONG)ll & BN_MASK2; | ||
105 | ll >>= BN_BITS2; | ||
106 | a++; | ||
107 | b++; | ||
108 | r++; | ||
109 | n--; | ||
110 | } | ||
111 | return ((BN_ULONG)ll); | ||
112 | } | ||
113 | #else /* !BN_LLONG */ | ||
114 | BN_ULONG | ||
115 | bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | ||
116 | { | ||
117 | BN_ULONG c, l, t; | ||
118 | |||
119 | assert(n >= 0); | ||
120 | if (n <= 0) | ||
121 | return ((BN_ULONG)0); | ||
122 | 85 | ||
123 | c = 0; | ||
124 | #ifndef OPENSSL_SMALL_FOOTPRINT | 86 | #ifndef OPENSSL_SMALL_FOOTPRINT |
125 | while (n & ~3) { | 87 | while (n & ~3) { |
126 | t = a[0]; | 88 | bn_addw_addw(a[0], b[0], carry, &carry, &r[0]); |
127 | t = (t + c) & BN_MASK2; | 89 | bn_addw_addw(a[1], b[1], carry, &carry, &r[1]); |
128 | c = (t < c); | 90 | bn_addw_addw(a[2], b[2], carry, &carry, &r[2]); |
129 | l = (t + b[0]) & BN_MASK2; | 91 | bn_addw_addw(a[3], b[3], carry, &carry, &r[3]); |
130 | c += (l < t); | ||
131 | r[0] = l; | ||
132 | t = a[1]; | ||
133 | t = (t + c) & BN_MASK2; | ||
134 | c = (t < c); | ||
135 | l = (t + b[1]) & BN_MASK2; | ||
136 | c += (l < t); | ||
137 | r[1] = l; | ||
138 | t = a[2]; | ||
139 | t = (t + c) & BN_MASK2; | ||
140 | c = (t < c); | ||
141 | l = (t + b[2]) & BN_MASK2; | ||
142 | c += (l < t); | ||
143 | r[2] = l; | ||
144 | t = a[3]; | ||
145 | t = (t + c) & BN_MASK2; | ||
146 | c = (t < c); | ||
147 | l = (t + b[3]) & BN_MASK2; | ||
148 | c += (l < t); | ||
149 | r[3] = l; | ||
150 | a += 4; | 92 | a += 4; |
151 | b += 4; | 93 | b += 4; |
152 | r += 4; | 94 | r += 4; |
@@ -154,55 +96,37 @@ bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | |||
154 | } | 96 | } |
155 | #endif | 97 | #endif |
156 | while (n) { | 98 | while (n) { |
157 | t = a[0]; | 99 | bn_addw_addw(a[0], b[0], carry, &carry, &r[0]); |
158 | t = (t + c) & BN_MASK2; | ||
159 | c = (t < c); | ||
160 | l = (t + b[0]) & BN_MASK2; | ||
161 | c += (l < t); | ||
162 | r[0] = l; | ||
163 | a++; | 100 | a++; |
164 | b++; | 101 | b++; |
165 | r++; | 102 | r++; |
166 | n--; | 103 | n--; |
167 | } | 104 | } |
168 | return ((BN_ULONG)c); | 105 | return carry; |
169 | } | 106 | } |
170 | #endif /* !BN_LLONG */ | ||
171 | #endif | 107 | #endif |
172 | 108 | ||
109 | /* | ||
110 | * bn_sub_words() computes (borrow:r[i]) = a[i] - b[i] - borrow, where a and b | ||
111 | * are both arrays of words. Any borrow resulting from the subtraction is | ||
112 | * returned. | ||
113 | */ | ||
173 | #ifndef HAVE_BN_SUB_WORDS | 114 | #ifndef HAVE_BN_SUB_WORDS |
174 | BN_ULONG | 115 | BN_ULONG |
175 | bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | 116 | bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) |
176 | { | 117 | { |
177 | BN_ULONG t1, t2; | 118 | BN_ULONG borrow = 0; |
178 | int c = 0; | ||
179 | 119 | ||
180 | assert(n >= 0); | 120 | assert(n >= 0); |
181 | if (n <= 0) | 121 | if (n <= 0) |
182 | return ((BN_ULONG)0); | 122 | return 0; |
183 | 123 | ||
184 | #ifndef OPENSSL_SMALL_FOOTPRINT | 124 | #ifndef OPENSSL_SMALL_FOOTPRINT |
185 | while (n&~3) { | 125 | while (n & ~3) { |
186 | t1 = a[0]; | 126 | bn_subw_subw(a[0], b[0], borrow, &borrow, &r[0]); |
187 | t2 = b[0]; | 127 | bn_subw_subw(a[1], b[1], borrow, &borrow, &r[1]); |
188 | r[0] = (t1 - t2 - c) & BN_MASK2; | 128 | bn_subw_subw(a[2], b[2], borrow, &borrow, &r[2]); |
189 | if (t1 != t2) | 129 | bn_subw_subw(a[3], b[3], borrow, &borrow, &r[3]); |
190 | c = (t1 < t2); | ||
191 | t1 = a[1]; | ||
192 | t2 = b[1]; | ||
193 | r[1] = (t1 - t2 - c) & BN_MASK2; | ||
194 | if (t1 != t2) | ||
195 | c = (t1 < t2); | ||
196 | t1 = a[2]; | ||
197 | t2 = b[2]; | ||
198 | r[2] = (t1 - t2 - c) & BN_MASK2; | ||
199 | if (t1 != t2) | ||
200 | c = (t1 < t2); | ||
201 | t1 = a[3]; | ||
202 | t2 = b[3]; | ||
203 | r[3] = (t1 - t2 - c) & BN_MASK2; | ||
204 | if (t1 != t2) | ||
205 | c = (t1 < t2); | ||
206 | a += 4; | 130 | a += 4; |
207 | b += 4; | 131 | b += 4; |
208 | r += 4; | 132 | r += 4; |
@@ -210,26 +134,22 @@ bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | |||
210 | } | 134 | } |
211 | #endif | 135 | #endif |
212 | while (n) { | 136 | while (n) { |
213 | t1 = a[0]; | 137 | bn_subw_subw(a[0], b[0], borrow, &borrow, &r[0]); |
214 | t2 = b[0]; | ||
215 | r[0] = (t1 - t2 - c) & BN_MASK2; | ||
216 | if (t1 != t2) | ||
217 | c = (t1 < t2); | ||
218 | a++; | 138 | a++; |
219 | b++; | 139 | b++; |
220 | r++; | 140 | r++; |
221 | n--; | 141 | n--; |
222 | } | 142 | } |
223 | return (c); | 143 | return borrow; |
224 | } | 144 | } |
225 | #endif | 145 | #endif |
226 | 146 | ||
227 | #ifndef HAVE_BN_ADD | ||
228 | /* | 147 | /* |
229 | * bn_add() computes a + b, storing the result in r (which may be the same as a | 148 | * bn_add() computes a + b, storing the result in r (which may be the same as a |
230 | * or b). The caller must ensure that r has been expanded to max(a->top, b->top) | 149 | * or b). The caller must ensure that r has been expanded to max(a->top, b->top) |
231 | * words. Any carry resulting from the addition is returned. | 150 | * words. Any carry resulting from the addition is returned. |
232 | */ | 151 | */ |
152 | #ifndef HAVE_BN_ADD | ||
233 | BN_ULONG | 153 | BN_ULONG |
234 | bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) | 154 | bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) |
235 | { | 155 | { |
@@ -268,13 +188,13 @@ bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) | |||
268 | } | 188 | } |
269 | #endif | 189 | #endif |
270 | 190 | ||
271 | #ifndef HAVE_BN_SUB | ||
272 | /* | 191 | /* |
273 | * bn_sub() computes a - b, storing the result in r (which may be the same as a | 192 | * bn_sub() computes a - b, storing the result in r (which may be the same as a |
274 | * or b). The caller must ensure that the number of words in a is greater than | 193 | * or b). The caller must ensure that the number of words in a is greater than |
275 | * or equal to the number of words in b and that r has been expanded to | 194 | * or equal to the number of words in b and that r has been expanded to |
276 | * a->top words. Any borrow resulting from the subtraction is returned. | 195 | * a->top words. Any borrow resulting from the subtraction is returned. |
277 | */ | 196 | */ |
197 | #ifndef HAVE_BN_SUB | ||
278 | BN_ULONG | 198 | BN_ULONG |
279 | bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) | 199 | bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) |
280 | { | 200 | { |
diff --git a/src/lib/libcrypto/bn/bn_internal.h b/src/lib/libcrypto/bn/bn_internal.h index 12ea3641e6..1b5ab9c42c 100644 --- a/src/lib/libcrypto/bn/bn_internal.h +++ b/src/lib/libcrypto/bn/bn_internal.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_internal.h,v 1.4 2023/02/15 04:46:49 tb Exp $ */ | 1 | /* $OpenBSD: bn_internal.h,v 1.5 2023/02/16 04:42:20 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -102,6 +102,63 @@ bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) | |||
102 | #endif | 102 | #endif |
103 | #endif | 103 | #endif |
104 | 104 | ||
105 | /* | ||
106 | * bn_addw_addw() computes (r1:r0) = a + b + c, where all inputs are single | ||
107 | * words, producing a double word result. | ||
108 | */ | ||
109 | #ifndef HAVE_BN_ADDW_ADDW | ||
110 | static inline void | ||
111 | bn_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1, | ||
112 | BN_ULONG *out_r0) | ||
113 | { | ||
114 | BN_ULONG carry, r1, r0; | ||
115 | |||
116 | bn_addw(a, b, &r1, &r0); | ||
117 | bn_addw(r0, c, &carry, &r0); | ||
118 | r1 += carry; | ||
119 | |||
120 | *out_r1 = r1; | ||
121 | *out_r0 = r0; | ||
122 | } | ||
123 | #endif | ||
124 | |||
125 | /* | ||
126 | * bn_subw() computes r0 = a - b, where both inputs are single words, | ||
127 | * producing a single word result and borrow. | ||
128 | */ | ||
129 | #ifndef HAVE_BN_SUBW | ||
130 | static inline void | ||
131 | bn_subw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_borrow, BN_ULONG *out_r0) | ||
132 | { | ||
133 | BN_ULONG borrow, r0; | ||
134 | |||
135 | r0 = a - b; | ||
136 | borrow = ((r0 | (b & ~a)) & (b | ~a)) >> (BN_BITS2 - 1); | ||
137 | |||
138 | *out_borrow = borrow; | ||
139 | *out_r0 = r0; | ||
140 | } | ||
141 | #endif | ||
142 | |||
143 | /* | ||
144 | * bn_subw_subw() computes r0 = a - b - c, where all inputs are single words, | ||
145 | * producing a single word result and borrow. | ||
146 | */ | ||
147 | #ifndef HAVE_BN_SUBW_SUBW | ||
148 | static inline void | ||
149 | bn_subw_subw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_borrow, | ||
150 | BN_ULONG *out_r0) | ||
151 | { | ||
152 | BN_ULONG b1, b2, r0; | ||
153 | |||
154 | bn_subw(a, b, &b1, &r0); | ||
155 | bn_subw(r0, c, &b2, &r0); | ||
156 | |||
157 | *out_borrow = b1 + b2; | ||
158 | *out_r0 = r0; | ||
159 | } | ||
160 | #endif | ||
161 | |||
105 | #ifndef HAVE_BN_UMUL_HILO | 162 | #ifndef HAVE_BN_UMUL_HILO |
106 | #ifdef BN_LLONG | 163 | #ifdef BN_LLONG |
107 | static inline void | 164 | static inline void |