summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_mont.c
diff options
context:
space:
mode:
authorjsing <>2014-05-08 13:20:49 +0000
committerjsing <>2014-05-08 13:20:49 +0000
commit2e8879604fe3abbc2431ca79a4a923f1e87da75e (patch)
tree18398455223278c0cb2bd44f57e4499a4370f665 /src/lib/libcrypto/bn/bn_mont.c
parentf7d9a959949e5f3918c1cf2b27fb4cd7b62d07d5 (diff)
downloadopenbsd-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.c478
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 @@
126static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); 126static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
127#endif 127#endif
128 128
129int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, 129int
130 BN_MONT_CTX *mont, BN_CTX *ctx) 130BN_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;
171err: 173err:
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
177static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) 179static int
178 { 180BN_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
265int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, 275int
266 BN_CTX *ctx) 276BN_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
317err:
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
306BN_MONT_CTX *BN_MONT_CTX_new(void) 323BN_MONT_CTX *
307 { 324BN_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
318void BN_MONT_CTX_init(BN_MONT_CTX *ctx) 336void
319 { 337BN_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
328void BN_MONT_CTX_free(BN_MONT_CTX *mont) 347void
329 { 348BN_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
340int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) 360int
341 { 361BN_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
445err: 485err:
446 BN_CTX_end(ctx); 486 BN_CTX_end(ctx);
447 return ret; 487 return ret;
448 } 488}
449 489
450BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) 490BN_MONT_CTX *
451 { 491BN_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;
463BN_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
508BN_MONT_CTX *
509BN_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}