diff options
author | jsing <> | 2014-05-08 13:20:49 +0000 |
---|---|---|
committer | jsing <> | 2014-05-08 13:20:49 +0000 |
commit | 2e8879604fe3abbc2431ca79a4a923f1e87da75e (patch) | |
tree | 18398455223278c0cb2bd44f57e4499a4370f665 /src/lib/libcrypto/bn/bn_mont.c | |
parent | f7d9a959949e5f3918c1cf2b27fb4cd7b62d07d5 (diff) | |
download | openbsd-2e8879604fe3abbc2431ca79a4a923f1e87da75e.tar.gz openbsd-2e8879604fe3abbc2431ca79a4a923f1e87da75e.tar.bz2 openbsd-2e8879604fe3abbc2431ca79a4a923f1e87da75e.zip |
Emergency knfectomie requested by tedu@.
Diffstat (limited to 'src/lib/libcrypto/bn/bn_mont.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_mont.c | 478 |
1 files changed, 261 insertions, 217 deletions
diff --git a/src/lib/libcrypto/bn/bn_mont.c b/src/lib/libcrypto/bn/bn_mont.c index 6274a934bb..073dfeffee 100644 --- a/src/lib/libcrypto/bn/bn_mont.c +++ b/src/lib/libcrypto/bn/bn_mont.c | |||
@@ -5,21 +5,21 @@ | |||
5 | * This package is an SSL implementation written | 5 | * This package is an SSL implementation written |
6 | * by Eric Young (eay@cryptsoft.com). | 6 | * by Eric Young (eay@cryptsoft.com). |
7 | * The implementation was written so as to conform with Netscapes SSL. | 7 | * The implementation was written so as to conform with Netscapes SSL. |
8 | * | 8 | * |
9 | * This library is free for commercial and non-commercial use as long as | 9 | * This library is free for commercial and non-commercial use as long as |
10 | * the following conditions are aheared to. The following conditions | 10 | * the following conditions are aheared to. The following conditions |
11 | * apply to all code found in this distribution, be it the RC4, RSA, | 11 | * apply to all code found in this distribution, be it the RC4, RSA, |
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | 12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
13 | * included with this distribution is covered by the same copyright terms | 13 | * included with this distribution is covered by the same copyright terms |
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | 14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
15 | * | 15 | * |
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | 16 | * Copyright remains Eric Young's, and as such any Copyright notices in |
17 | * the code are not to be removed. | 17 | * the code are not to be removed. |
18 | * If this package is used in a product, Eric Young should be given attribution | 18 | * If this package is used in a product, Eric Young should be given attribution |
19 | * as the author of the parts of the library used. | 19 | * as the author of the parts of the library used. |
20 | * This can be in the form of a textual message at program startup or | 20 | * This can be in the form of a textual message at program startup or |
21 | * in documentation (online or textual) provided with the package. | 21 | * in documentation (online or textual) provided with the package. |
22 | * | 22 | * |
23 | * Redistribution and use in source and binary forms, with or without | 23 | * Redistribution and use in source and binary forms, with or without |
24 | * modification, are permitted provided that the following conditions | 24 | * modification, are permitted provided that the following conditions |
25 | * are met: | 25 | * are met: |
@@ -34,10 +34,10 @@ | |||
34 | * Eric Young (eay@cryptsoft.com)" | 34 | * Eric Young (eay@cryptsoft.com)" |
35 | * The word 'cryptographic' can be left out if the rouines from the library | 35 | * The word 'cryptographic' can be left out if the rouines from the library |
36 | * being used are not cryptographic related :-). | 36 | * being used are not cryptographic related :-). |
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | 37 | * 4. If you include any Windows specific code (or a derivative thereof) from |
38 | * the apps directory (application code) you must include an acknowledgement: | 38 | * the apps directory (application code) you must include an acknowledgement: |
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | 39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
40 | * | 40 | * |
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | 41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
@@ -49,7 +49,7 @@ | |||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
51 | * SUCH DAMAGE. | 51 | * SUCH DAMAGE. |
52 | * | 52 | * |
53 | * The licence and distribution terms for any publically available version or | 53 | * The licence and distribution terms for any publically available version or |
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | 54 | * derivative of this code cannot be changed. i.e. this code cannot simply be |
55 | * copied and put under another distribution licence | 55 | * copied and put under another distribution licence |
@@ -63,7 +63,7 @@ | |||
63 | * are met: | 63 | * are met: |
64 | * | 64 | * |
65 | * 1. Redistributions of source code must retain the above copyright | 65 | * 1. Redistributions of source code must retain the above copyright |
66 | * notice, this list of conditions and the following disclaimer. | 66 | * notice, this list of conditions and the following disclaimer. |
67 | * | 67 | * |
68 | * 2. Redistributions in binary form must reproduce the above copyright | 68 | * 2. Redistributions in binary form must reproduce the above copyright |
69 | * notice, this list of conditions and the following disclaimer in | 69 | * notice, this list of conditions and the following disclaimer in |
@@ -126,239 +126,263 @@ | |||
126 | static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); | 126 | static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); |
127 | #endif | 127 | #endif |
128 | 128 | ||
129 | int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | 129 | int |
130 | BN_MONT_CTX *mont, BN_CTX *ctx) | 130 | BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, |
131 | { | 131 | BN_MONT_CTX *mont, BN_CTX *ctx) |
132 | { | ||
132 | BIGNUM *tmp; | 133 | BIGNUM *tmp; |
133 | int ret=0; | 134 | int ret = 0; |
134 | #if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD) | 135 | #if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD) |
135 | int num = mont->N.top; | 136 | int num = mont->N.top; |
136 | 137 | ||
137 | if (num>1 && a->top==num && b->top==num) | 138 | if (num > 1 && a->top == num && b->top == num) { |
138 | { | 139 | if (bn_wexpand(r, num) == NULL) |
139 | if (bn_wexpand(r,num) == NULL) return(0); | 140 | return (0); |
140 | if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num)) | 141 | if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { |
141 | { | ||
142 | r->neg = a->neg^b->neg; | 142 | r->neg = a->neg^b->neg; |
143 | r->top = num; | 143 | r->top = num; |
144 | bn_correct_top(r); | 144 | bn_correct_top(r); |
145 | return(1); | 145 | return (1); |
146 | } | ||
147 | } | 146 | } |
147 | } | ||
148 | #endif | 148 | #endif |
149 | 149 | ||
150 | BN_CTX_start(ctx); | 150 | BN_CTX_start(ctx); |
151 | tmp = BN_CTX_get(ctx); | 151 | tmp = BN_CTX_get(ctx); |
152 | if (tmp == NULL) goto err; | 152 | if (tmp == NULL) |
153 | goto err; | ||
153 | 154 | ||
154 | bn_check_top(tmp); | 155 | bn_check_top(tmp); |
155 | if (a == b) | 156 | if (a == b) { |
156 | { | 157 | if (!BN_sqr(tmp, a, ctx)) |
157 | if (!BN_sqr(tmp,a,ctx)) goto err; | 158 | goto err; |
158 | } | 159 | } else { |
159 | else | 160 | if (!BN_mul(tmp, a,b, ctx)) |
160 | { | 161 | goto err; |
161 | if (!BN_mul(tmp,a,b,ctx)) goto err; | 162 | } |
162 | } | ||
163 | /* reduce from aRR to aR */ | 163 | /* reduce from aRR to aR */ |
164 | #ifdef MONT_WORD | 164 | #ifdef MONT_WORD |
165 | if (!BN_from_montgomery_word(r,tmp,mont)) goto err; | 165 | if (!BN_from_montgomery_word(r, tmp, mont)) |
166 | goto err; | ||
166 | #else | 167 | #else |
167 | if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; | 168 | if (!BN_from_montgomery(r, tmp, mont, ctx)) |
169 | goto err; | ||
168 | #endif | 170 | #endif |
169 | bn_check_top(r); | 171 | bn_check_top(r); |
170 | ret=1; | 172 | ret = 1; |
171 | err: | 173 | err: |
172 | BN_CTX_end(ctx); | 174 | BN_CTX_end(ctx); |
173 | return(ret); | 175 | return (ret); |
174 | } | 176 | } |
175 | 177 | ||
176 | #ifdef MONT_WORD | 178 | #ifdef MONT_WORD |
177 | static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) | 179 | static int |
178 | { | 180 | BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) |
181 | { | ||
179 | BIGNUM *n; | 182 | BIGNUM *n; |
180 | BN_ULONG *ap,*np,*rp,n0,v,carry; | 183 | BN_ULONG *ap, *np, *rp, n0, v, carry; |
181 | int nl,max,i; | 184 | int nl, max, i; |
182 | 185 | ||
183 | n= &(mont->N); | 186 | n = &(mont->N); |
184 | nl=n->top; | 187 | nl = n->top; |
185 | if (nl == 0) { ret->top=0; return(1); } | 188 | if (nl == 0) { |
189 | ret->top = 0; | ||
190 | return (1); | ||
191 | } | ||
186 | 192 | ||
187 | max=(2*nl); /* carry is stored separately */ | 193 | max = (2 * nl); /* carry is stored separately */ |
188 | if (bn_wexpand(r,max) == NULL) return(0); | 194 | if (bn_wexpand(r, max) == NULL) |
195 | return (0); | ||
189 | 196 | ||
190 | r->neg^=n->neg; | 197 | r->neg ^= n->neg; |
191 | np=n->d; | 198 | np = n->d; |
192 | rp=r->d; | 199 | rp = r->d; |
193 | 200 | ||
194 | /* clear the top words of T */ | 201 | /* clear the top words of T */ |
195 | #if 1 | 202 | #if 1 |
196 | for (i=r->top; i<max; i++) /* memset? XXX */ | 203 | for (i=r->top; i<max; i++) /* memset? XXX */ |
197 | rp[i]=0; | 204 | rp[i] = 0; |
198 | #else | 205 | #else |
199 | memset(&(rp[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); | 206 | memset(&(rp[r->top]), 0, (max - r->top) * sizeof(BN_ULONG)); |
200 | #endif | 207 | #endif |
201 | 208 | ||
202 | r->top=max; | 209 | r->top = max; |
203 | n0=mont->n0[0]; | 210 | n0 = mont->n0[0]; |
204 | 211 | ||
205 | #ifdef BN_COUNT | 212 | #ifdef BN_COUNT |
206 | fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl); | 213 | fprintf(stderr, "word BN_from_montgomery_word %d * %d\n", nl, nl); |
207 | #endif | 214 | #endif |
208 | for (carry=0, i=0; i<nl; i++, rp++) | 215 | for (carry = 0, i = 0; i < nl; i++, rp++) { |
209 | { | 216 | v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2); |
210 | v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2); | 217 | v = (v + carry + rp[nl]) & BN_MASK2; |
211 | v = (v+carry+rp[nl])&BN_MASK2; | ||
212 | carry |= (v != rp[nl]); | 218 | carry |= (v != rp[nl]); |
213 | carry &= (v <= rp[nl]); | 219 | carry &= (v <= rp[nl]); |
214 | rp[nl]=v; | 220 | rp[nl] = v; |
215 | } | 221 | } |
216 | 222 | ||
217 | if (bn_wexpand(ret,nl) == NULL) return(0); | 223 | if (bn_wexpand(ret, nl) == NULL) |
218 | ret->top=nl; | 224 | return (0); |
219 | ret->neg=r->neg; | 225 | ret->top = nl; |
226 | ret->neg = r->neg; | ||
220 | 227 | ||
221 | rp=ret->d; | 228 | rp = ret->d; |
222 | ap=&(r->d[nl]); | 229 | ap = &(r->d[nl]); |
223 | 230 | ||
224 | #define BRANCH_FREE 1 | 231 | #define BRANCH_FREE 1 |
225 | #if BRANCH_FREE | 232 | #if BRANCH_FREE |
226 | { | 233 | { |
227 | BN_ULONG *nrp; | 234 | BN_ULONG *nrp; |
228 | size_t m; | 235 | size_t m; |
229 | 236 | ||
230 | v=bn_sub_words(rp,ap,np,nl)-carry; | 237 | v = bn_sub_words(rp, ap, np, nl) - carry; |
231 | /* if subtraction result is real, then | 238 | /* if subtraction result is real, then |
232 | * trick unconditional memcpy below to perform in-place | 239 | * trick unconditional memcpy below to perform in-place |
233 | * "refresh" instead of actual copy. */ | 240 | * "refresh" instead of actual copy. */ |
234 | m=(0-(size_t)v); | 241 | m = (0 - (size_t)v); |
235 | nrp=(BN_ULONG *)(((uintptr_t)rp&~m)|((uintptr_t)ap&m)); | 242 | nrp = (BN_ULONG *)(((uintptr_t)rp & ~m)|((uintptr_t)ap & m)); |
236 | 243 | ||
237 | for (i=0,nl-=4; i<nl; i+=4) | 244 | for (i = 0, nl -= 4; i < nl; i += 4) { |
238 | { | 245 | BN_ULONG t1, t2, t3, t4; |
239 | BN_ULONG t1,t2,t3,t4; | 246 | |
240 | 247 | t1 = nrp[i + 0]; | |
241 | t1=nrp[i+0]; | 248 | t2 = nrp[i + 1]; |
242 | t2=nrp[i+1]; | 249 | t3 = nrp[i + 2]; |
243 | t3=nrp[i+2]; ap[i+0]=0; | 250 | ap[i + 0] = 0; |
244 | t4=nrp[i+3]; ap[i+1]=0; | 251 | t4 = nrp[i + 3]; |
245 | rp[i+0]=t1; ap[i+2]=0; | 252 | ap[i + 1] = 0; |
246 | rp[i+1]=t2; ap[i+3]=0; | 253 | rp[i + 0] = t1; |
247 | rp[i+2]=t3; | 254 | ap[i + 2] = 0; |
248 | rp[i+3]=t4; | 255 | rp[i + 1] = t2; |
256 | ap[i + 3] = 0; | ||
257 | rp[i + 2] = t3; | ||
258 | rp[i + 3] = t4; | ||
249 | } | 259 | } |
250 | for (nl+=4; i<nl; i++) | 260 | for (nl += 4; i < nl; i++) |
251 | rp[i]=nrp[i], ap[i]=0; | 261 | rp[i] = nrp[i], ap[i] = 0; |
252 | } | 262 | } |
253 | #else | 263 | #else |
254 | if (bn_sub_words (rp,ap,np,nl)-carry) | 264 | if (bn_sub_words (rp, ap, np, nl) - carry) |
255 | memcpy(rp,ap,nl*sizeof(BN_ULONG)); | 265 | memcpy(rp, ap, nl*sizeof(BN_ULONG)); |
256 | #endif | 266 | #endif |
257 | bn_correct_top(r); | 267 | bn_correct_top(r); |
258 | bn_correct_top(ret); | 268 | bn_correct_top(ret); |
259 | bn_check_top(ret); | 269 | bn_check_top(ret); |
260 | 270 | ||
261 | return(1); | 271 | return (1); |
262 | } | 272 | } |
263 | #endif /* MONT_WORD */ | 273 | #endif /* MONT_WORD */ |
264 | 274 | ||
265 | int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, | 275 | int |
266 | BN_CTX *ctx) | 276 | BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) |
267 | { | 277 | { |
268 | int retn=0; | 278 | int retn = 0; |
269 | #ifdef MONT_WORD | 279 | #ifdef MONT_WORD |
270 | BIGNUM *t; | 280 | BIGNUM *t; |
271 | 281 | ||
272 | BN_CTX_start(ctx); | 282 | BN_CTX_start(ctx); |
273 | if ((t = BN_CTX_get(ctx)) && BN_copy(t,a)) | 283 | if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) |
274 | retn = BN_from_montgomery_word(ret,t,mont); | 284 | retn = BN_from_montgomery_word(ret, t, mont); |
275 | BN_CTX_end(ctx); | 285 | BN_CTX_end(ctx); |
276 | #else /* !MONT_WORD */ | 286 | #else /* !MONT_WORD */ |
277 | BIGNUM *t1,*t2; | 287 | BIGNUM *t1, *t2; |
278 | 288 | ||
279 | BN_CTX_start(ctx); | 289 | BN_CTX_start(ctx); |
280 | t1 = BN_CTX_get(ctx); | 290 | t1 = BN_CTX_get(ctx); |
281 | t2 = BN_CTX_get(ctx); | 291 | t2 = BN_CTX_get(ctx); |
282 | if (t1 == NULL || t2 == NULL) goto err; | 292 | if (t1 == NULL || t2 == NULL) |
283 | 293 | goto err; | |
284 | if (!BN_copy(t1,a)) goto err; | 294 | |
285 | BN_mask_bits(t1,mont->ri); | 295 | if (!BN_copy(t1, a)) |
286 | 296 | goto err; | |
287 | if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err; | 297 | BN_mask_bits(t1, mont->ri); |
288 | BN_mask_bits(t2,mont->ri); | 298 | |
289 | 299 | if (!BN_mul(t2, t1, &mont->Ni, ctx)) | |
290 | if (!BN_mul(t1,t2,&mont->N,ctx)) goto err; | 300 | goto err; |
291 | if (!BN_add(t2,a,t1)) goto err; | 301 | BN_mask_bits(t2, mont->ri); |
292 | if (!BN_rshift(ret,t2,mont->ri)) goto err; | 302 | |
293 | 303 | if (!BN_mul(t1, t2, &mont->N, ctx)) | |
294 | if (BN_ucmp(ret, &(mont->N)) >= 0) | 304 | goto err; |
295 | { | 305 | if (!BN_add(t2, a, t1)) |
296 | if (!BN_usub(ret,ret,&(mont->N))) goto err; | 306 | goto err; |
297 | } | 307 | if (!BN_rshift(ret, t2, mont->ri)) |
298 | retn=1; | 308 | goto err; |
309 | |||
310 | if (BN_ucmp(ret, &(mont->N)) >= 0) { | ||
311 | if (!BN_usub(ret, ret, &(mont->N))) | ||
312 | goto err; | ||
313 | } | ||
314 | retn = 1; | ||
299 | bn_check_top(ret); | 315 | bn_check_top(ret); |
300 | err: | 316 | |
317 | err: | ||
301 | BN_CTX_end(ctx); | 318 | BN_CTX_end(ctx); |
302 | #endif /* MONT_WORD */ | 319 | #endif /* MONT_WORD */ |
303 | return(retn); | 320 | return (retn); |
304 | } | 321 | } |
305 | 322 | ||
306 | BN_MONT_CTX *BN_MONT_CTX_new(void) | 323 | BN_MONT_CTX * |
307 | { | 324 | BN_MONT_CTX_new(void) |
325 | { | ||
308 | BN_MONT_CTX *ret; | 326 | BN_MONT_CTX *ret; |
309 | 327 | ||
310 | if ((ret=(BN_MONT_CTX *)malloc(sizeof(BN_MONT_CTX))) == NULL) | 328 | if ((ret = (BN_MONT_CTX *)malloc(sizeof(BN_MONT_CTX))) == NULL) |
311 | return(NULL); | 329 | return (NULL); |
312 | 330 | ||
313 | BN_MONT_CTX_init(ret); | 331 | BN_MONT_CTX_init(ret); |
314 | ret->flags=BN_FLG_MALLOCED; | 332 | ret->flags = BN_FLG_MALLOCED; |
315 | return(ret); | 333 | return (ret); |
316 | } | 334 | } |
317 | 335 | ||
318 | void BN_MONT_CTX_init(BN_MONT_CTX *ctx) | 336 | void |
319 | { | 337 | BN_MONT_CTX_init(BN_MONT_CTX *ctx) |
320 | ctx->ri=0; | 338 | { |
339 | ctx->ri = 0; | ||
321 | BN_init(&(ctx->RR)); | 340 | BN_init(&(ctx->RR)); |
322 | BN_init(&(ctx->N)); | 341 | BN_init(&(ctx->N)); |
323 | BN_init(&(ctx->Ni)); | 342 | BN_init(&(ctx->Ni)); |
324 | ctx->n0[0] = ctx->n0[1] = 0; | 343 | ctx->n0[0] = ctx->n0[1] = 0; |
325 | ctx->flags=0; | 344 | ctx->flags = 0; |
326 | } | 345 | } |
327 | 346 | ||
328 | void BN_MONT_CTX_free(BN_MONT_CTX *mont) | 347 | void |
329 | { | 348 | BN_MONT_CTX_free(BN_MONT_CTX *mont) |
330 | if(mont == NULL) | 349 | { |
331 | return; | 350 | if (mont == NULL) |
351 | return; | ||
332 | 352 | ||
333 | BN_clear_free(&(mont->RR)); | 353 | BN_clear_free(&(mont->RR)); |
334 | BN_clear_free(&(mont->N)); | 354 | BN_clear_free(&(mont->N)); |
335 | BN_clear_free(&(mont->Ni)); | 355 | BN_clear_free(&(mont->Ni)); |
336 | if (mont->flags & BN_FLG_MALLOCED) | 356 | if (mont->flags & BN_FLG_MALLOCED) |
337 | free(mont); | 357 | free(mont); |
338 | } | 358 | } |
339 | 359 | ||
340 | int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) | 360 | int |
341 | { | 361 | BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) |
362 | { | ||
342 | int ret = 0; | 363 | int ret = 0; |
343 | BIGNUM *Ri,*R; | 364 | BIGNUM *Ri, *R; |
344 | 365 | ||
345 | BN_CTX_start(ctx); | 366 | BN_CTX_start(ctx); |
346 | if((Ri = BN_CTX_get(ctx)) == NULL) goto err; | 367 | if ((Ri = BN_CTX_get(ctx)) == NULL) |
347 | R= &(mont->RR); /* grab RR as a temp */ | 368 | goto err; |
348 | if (!BN_copy(&(mont->N),mod)) goto err; /* Set N */ | 369 | R = &(mont->RR); /* grab RR as a temp */ |
370 | if (!BN_copy(&(mont->N), mod)) | ||
371 | goto err; /* Set N */ | ||
349 | mont->N.neg = 0; | 372 | mont->N.neg = 0; |
350 | 373 | ||
351 | #ifdef MONT_WORD | 374 | #ifdef MONT_WORD |
352 | { | 375 | { |
353 | BIGNUM tmod; | 376 | BIGNUM tmod; |
354 | BN_ULONG buf[2]; | 377 | BN_ULONG buf[2]; |
355 | 378 | ||
356 | BN_init(&tmod); | 379 | BN_init(&tmod); |
357 | tmod.d=buf; | 380 | tmod.d = buf; |
358 | tmod.dmax=2; | 381 | tmod.dmax = 2; |
359 | tmod.neg=0; | 382 | tmod.neg = 0; |
360 | 383 | ||
361 | mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; | 384 | mont->ri = (BN_num_bits(mod) + |
385 | (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; | ||
362 | 386 | ||
363 | #if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) | 387 | #if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) |
364 | /* Only certain BN_BITS2<=32 platforms actually make use of | 388 | /* Only certain BN_BITS2<=32 platforms actually make use of |
@@ -367,128 +391,148 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) | |||
367 | * files do know which is which. */ | 391 | * files do know which is which. */ |
368 | 392 | ||
369 | BN_zero(R); | 393 | BN_zero(R); |
370 | if (!(BN_set_bit(R,2*BN_BITS2))) goto err; | 394 | if (!(BN_set_bit(R, 2 * BN_BITS2))) |
395 | goto err; | ||
371 | 396 | ||
372 | tmod.top=0; | 397 | tmod.top = 0; |
373 | if ((buf[0] = mod->d[0])) tmod.top=1; | 398 | if ((buf[0] = mod->d[0])) |
374 | if ((buf[1] = mod->top>1 ? mod->d[1] : 0)) tmod.top=2; | 399 | tmod.top = 1; |
400 | if ((buf[1] = mod->top > 1 ? mod->d[1] : 0)) | ||
401 | tmod.top = 2; | ||
375 | 402 | ||
376 | if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL) | 403 | if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) |
377 | goto err; | 404 | goto err; |
378 | if (!BN_lshift(Ri,Ri,2*BN_BITS2)) goto err; /* R*Ri */ | 405 | if (!BN_lshift(Ri, Ri, 2 * BN_BITS2)) |
379 | if (!BN_is_zero(Ri)) | 406 | goto err; /* R*Ri */ |
380 | { | 407 | if (!BN_is_zero(Ri)) { |
381 | if (!BN_sub_word(Ri,1)) goto err; | 408 | if (!BN_sub_word(Ri, 1)) |
382 | } | 409 | goto err; |
410 | } | ||
383 | else /* if N mod word size == 1 */ | 411 | else /* if N mod word size == 1 */ |
384 | { | 412 | { |
385 | if (bn_expand(Ri,(int)sizeof(BN_ULONG)*2) == NULL) | 413 | if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL) |
386 | goto err; | 414 | goto err; |
387 | /* Ri-- (mod double word size) */ | 415 | /* Ri-- (mod double word size) */ |
388 | Ri->neg=0; | 416 | Ri->neg = 0; |
389 | Ri->d[0]=BN_MASK2; | 417 | Ri->d[0] = BN_MASK2; |
390 | Ri->d[1]=BN_MASK2; | 418 | Ri->d[1] = BN_MASK2; |
391 | Ri->top=2; | 419 | Ri->top = 2; |
392 | } | 420 | } |
393 | if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err; | 421 | if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) |
422 | goto err; | ||
394 | /* Ni = (R*Ri-1)/N, | 423 | /* Ni = (R*Ri-1)/N, |
395 | * keep only couple of least significant words: */ | 424 | * keep only couple of least significant words: */ |
396 | mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; | 425 | mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; |
397 | mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; | 426 | mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; |
398 | #else | 427 | #else |
399 | BN_zero(R); | 428 | BN_zero(R); |
400 | if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */ | 429 | if (!(BN_set_bit(R, BN_BITS2))) |
430 | goto err; /* R */ | ||
401 | 431 | ||
402 | buf[0]=mod->d[0]; /* tmod = N mod word size */ | 432 | buf[0] = mod->d[0]; /* tmod = N mod word size */ |
403 | buf[1]=0; | 433 | buf[1] = 0; |
404 | tmod.top = buf[0] != 0 ? 1 : 0; | 434 | tmod.top = buf[0] != 0 ? 1 : 0; |
405 | /* Ri = R^-1 mod N*/ | 435 | /* Ri = R^-1 mod N*/ |
406 | if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL) | 436 | if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) |
407 | goto err; | 437 | goto err; |
408 | if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */ | 438 | if (!BN_lshift(Ri, Ri, BN_BITS2)) |
409 | if (!BN_is_zero(Ri)) | 439 | goto err; /* R*Ri */ |
410 | { | 440 | if (!BN_is_zero(Ri)) { |
411 | if (!BN_sub_word(Ri,1)) goto err; | 441 | if (!BN_sub_word(Ri, 1)) |
412 | } | 442 | goto err; |
443 | } | ||
413 | else /* if N mod word size == 1 */ | 444 | else /* if N mod word size == 1 */ |
414 | { | 445 | { |
415 | if (!BN_set_word(Ri,BN_MASK2)) goto err; /* Ri-- (mod word size) */ | 446 | if (!BN_set_word(Ri, BN_MASK2)) |
416 | } | 447 | goto err; /* Ri-- (mod word size) */ |
417 | if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err; | 448 | } |
449 | if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) | ||
450 | goto err; | ||
418 | /* Ni = (R*Ri-1)/N, | 451 | /* Ni = (R*Ri-1)/N, |
419 | * keep only least significant word: */ | 452 | * keep only least significant word: */ |
420 | mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; | 453 | mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; |
421 | mont->n0[1] = 0; | 454 | mont->n0[1] = 0; |
422 | #endif | 455 | #endif |
423 | } | 456 | } |
424 | #else /* !MONT_WORD */ | 457 | #else /* !MONT_WORD */ |
425 | { /* bignum version */ | 458 | { /* bignum version */ |
426 | mont->ri=BN_num_bits(&mont->N); | 459 | mont->ri = BN_num_bits(&mont->N); |
427 | BN_zero(R); | 460 | BN_zero(R); |
428 | if (!BN_set_bit(R,mont->ri)) goto err; /* R = 2^ri */ | 461 | if (!BN_set_bit(R, mont->ri)) |
429 | /* Ri = R^-1 mod N*/ | 462 | goto err; /* R = 2^ri */ |
430 | if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL) | 463 | /* Ri = R^-1 mod N*/ |
464 | if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL) | ||
431 | goto err; | 465 | goto err; |
432 | if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */ | 466 | if (!BN_lshift(Ri, Ri, mont->ri)) |
433 | if (!BN_sub_word(Ri,1)) goto err; | 467 | goto err; /* R*Ri */ |
434 | /* Ni = (R*Ri-1) / N */ | 468 | if (!BN_sub_word(Ri, 1)) |
435 | if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err; | 469 | goto err; |
436 | } | 470 | /* Ni = (R*Ri-1) / N */ |
471 | if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx)) | ||
472 | goto err; | ||
473 | } | ||
437 | #endif | 474 | #endif |
438 | 475 | ||
439 | /* setup RR for conversions */ | 476 | /* setup RR for conversions */ |
440 | BN_zero(&(mont->RR)); | 477 | BN_zero(&(mont->RR)); |
441 | if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err; | 478 | if (!BN_set_bit(&(mont->RR), mont->ri*2)) |
442 | if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err; | 479 | goto err; |
480 | if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) | ||
481 | goto err; | ||
443 | 482 | ||
444 | ret = 1; | 483 | ret = 1; |
484 | |||
445 | err: | 485 | err: |
446 | BN_CTX_end(ctx); | 486 | BN_CTX_end(ctx); |
447 | return ret; | 487 | return ret; |
448 | } | 488 | } |
449 | 489 | ||
450 | BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) | 490 | BN_MONT_CTX * |
451 | { | 491 | BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) |
452 | if (to == from) return(to); | 492 | { |
453 | 493 | if (to == from) | |
454 | if (!BN_copy(&(to->RR),&(from->RR))) return NULL; | 494 | return (to); |
455 | if (!BN_copy(&(to->N),&(from->N))) return NULL; | 495 | |
456 | if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL; | 496 | if (!BN_copy(&(to->RR), &(from->RR))) |
457 | to->ri=from->ri; | 497 | return NULL; |
458 | to->n0[0]=from->n0[0]; | 498 | if (!BN_copy(&(to->N), &(from->N))) |
459 | to->n0[1]=from->n0[1]; | 499 | return NULL; |
460 | return(to); | 500 | if (!BN_copy(&(to->Ni), &(from->Ni))) |
461 | } | 501 | return NULL; |
462 | 502 | to->ri = from->ri; | |
463 | BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, | 503 | to->n0[0] = from->n0[0]; |
464 | const BIGNUM *mod, BN_CTX *ctx) | 504 | to->n0[1] = from->n0[1]; |
465 | { | 505 | return (to); |
506 | } | ||
507 | |||
508 | BN_MONT_CTX * | ||
509 | BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, const BIGNUM *mod, | ||
510 | BN_CTX *ctx) | ||
511 | { | ||
466 | int got_write_lock = 0; | 512 | int got_write_lock = 0; |
467 | BN_MONT_CTX *ret; | 513 | BN_MONT_CTX *ret; |
468 | 514 | ||
469 | CRYPTO_r_lock(lock); | 515 | CRYPTO_r_lock(lock); |
470 | if (!*pmont) | 516 | if (!*pmont) { |
471 | { | ||
472 | CRYPTO_r_unlock(lock); | 517 | CRYPTO_r_unlock(lock); |
473 | CRYPTO_w_lock(lock); | 518 | CRYPTO_w_lock(lock); |
474 | got_write_lock = 1; | 519 | got_write_lock = 1; |
475 | 520 | ||
476 | if (!*pmont) | 521 | if (!*pmont) { |
477 | { | ||
478 | ret = BN_MONT_CTX_new(); | 522 | ret = BN_MONT_CTX_new(); |
479 | if (ret && !BN_MONT_CTX_set(ret, mod, ctx)) | 523 | if (ret && !BN_MONT_CTX_set(ret, mod, ctx)) |
480 | BN_MONT_CTX_free(ret); | 524 | BN_MONT_CTX_free(ret); |
481 | else | 525 | else |
482 | *pmont = ret; | 526 | *pmont = ret; |
483 | } | ||
484 | } | 527 | } |
485 | 528 | } | |
529 | |||
486 | ret = *pmont; | 530 | ret = *pmont; |
487 | 531 | ||
488 | if (got_write_lock) | 532 | if (got_write_lock) |
489 | CRYPTO_w_unlock(lock); | 533 | CRYPTO_w_unlock(lock); |
490 | else | 534 | else |
491 | CRYPTO_r_unlock(lock); | 535 | CRYPTO_r_unlock(lock); |
492 | 536 | ||
493 | return ret; | 537 | return ret; |
494 | } | 538 | } |