/src/openssl30/crypto/bn/bn_mont.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 1995-2023 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 |  | /* | 
| 11 |  |  * Details about Montgomery multiplication algorithms can be found at | 
| 12 |  |  * http://security.ece.orst.edu/publications.html, e.g. | 
| 13 |  |  * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and | 
| 14 |  |  * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf | 
| 15 |  |  */ | 
| 16 |  |  | 
| 17 |  | #include "internal/cryptlib.h" | 
| 18 |  | #include "bn_local.h" | 
| 19 |  |  | 
| 20 |  | #define MONT_WORD               /* use the faster word-based algorithm */ | 
| 21 |  |  | 
| 22 |  | #ifdef MONT_WORD | 
| 23 |  | static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); | 
| 24 |  | #endif | 
| 25 |  |  | 
| 26 |  | int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | 
| 27 |  |                           BN_MONT_CTX *mont, BN_CTX *ctx) | 
| 28 | 27.2M | { | 
| 29 | 27.2M |     int ret = bn_mul_mont_fixed_top(r, a, b, mont, ctx); | 
| 30 |  |  | 
| 31 | 27.2M |     bn_correct_top(r); | 
| 32 | 27.2M |     bn_check_top(r); | 
| 33 |  |  | 
| 34 | 27.2M |     return ret; | 
| 35 | 27.2M | } | 
| 36 |  |  | 
| 37 |  | int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | 
| 38 |  |                           BN_MONT_CTX *mont, BN_CTX *ctx) | 
| 39 | 58.2M | { | 
| 40 | 58.2M |     BIGNUM *tmp; | 
| 41 | 58.2M |     int ret = 0; | 
| 42 | 58.2M |     int num = mont->N.top; | 
| 43 |  |  | 
| 44 | 58.2M | #if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD) | 
| 45 | 58.2M |     if (num > 1 && num <= BN_SOFT_LIMIT && a->top == num && b->top == num) { | 
| 46 | 55.3M |         if (bn_wexpand(r, num) == NULL) | 
| 47 | 0 |             return 0; | 
| 48 | 55.3M |         if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { | 
| 49 | 55.3M |             r->neg = a->neg ^ b->neg; | 
| 50 | 55.3M |             r->top = num; | 
| 51 | 55.3M |             r->flags |= BN_FLG_FIXED_TOP; | 
| 52 | 55.3M |             return 1; | 
| 53 | 55.3M |         } | 
| 54 | 55.3M |     } | 
| 55 | 2.90M | #endif | 
| 56 |  |  | 
| 57 | 2.90M |     if ((a->top + b->top) > 2 * num) | 
| 58 | 0 |         return 0; | 
| 59 |  |  | 
| 60 | 2.90M |     BN_CTX_start(ctx); | 
| 61 | 2.90M |     tmp = BN_CTX_get(ctx); | 
| 62 | 2.90M |     if (tmp == NULL) | 
| 63 | 0 |         goto err; | 
| 64 |  |  | 
| 65 | 2.90M |     bn_check_top(tmp); | 
| 66 | 2.90M |     if (a == b) { | 
| 67 | 1.23M |         if (!bn_sqr_fixed_top(tmp, a, ctx)) | 
| 68 | 0 |             goto err; | 
| 69 | 1.66M |     } else { | 
| 70 | 1.66M |         if (!bn_mul_fixed_top(tmp, a, b, ctx)) | 
| 71 | 0 |             goto err; | 
| 72 | 1.66M |     } | 
| 73 |  |     /* reduce from aRR to aR */ | 
| 74 | 2.90M | #ifdef MONT_WORD | 
| 75 | 2.90M |     if (!bn_from_montgomery_word(r, tmp, mont)) | 
| 76 | 0 |         goto err; | 
| 77 |  | #else | 
| 78 |  |     if (!BN_from_montgomery(r, tmp, mont, ctx)) | 
| 79 |  |         goto err; | 
| 80 |  | #endif | 
| 81 | 2.90M |     ret = 1; | 
| 82 | 2.90M |  err: | 
| 83 | 2.90M |     BN_CTX_end(ctx); | 
| 84 | 2.90M |     return ret; | 
| 85 | 2.90M | } | 
| 86 |  |  | 
| 87 |  | #ifdef MONT_WORD | 
| 88 |  | static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) | 
| 89 | 3.34M | { | 
| 90 | 3.34M |     BIGNUM *n; | 
| 91 | 3.34M |     BN_ULONG *ap, *np, *rp, n0, v, carry; | 
| 92 | 3.34M |     int nl, max, i; | 
| 93 | 3.34M |     unsigned int rtop; | 
| 94 |  |  | 
| 95 | 3.34M |     n = &(mont->N); | 
| 96 | 3.34M |     nl = n->top; | 
| 97 | 3.34M |     if (nl == 0) { | 
| 98 | 0 |         ret->top = 0; | 
| 99 | 0 |         return 1; | 
| 100 | 0 |     } | 
| 101 |  |  | 
| 102 | 3.34M |     max = (2 * nl);             /* carry is stored separately */ | 
| 103 | 3.34M |     if (bn_wexpand(r, max) == NULL) | 
| 104 | 0 |         return 0; | 
| 105 |  |  | 
| 106 | 3.34M |     r->neg ^= n->neg; | 
| 107 | 3.34M |     np = n->d; | 
| 108 | 3.34M |     rp = r->d; | 
| 109 |  |  | 
| 110 |  |     /* clear the top words of T */ | 
| 111 | 80.3M |     for (rtop = r->top, i = 0; i < max; i++) { | 
| 112 | 77.0M |         v = (BN_ULONG)0 - ((i - rtop) >> (8 * sizeof(rtop) - 1)); | 
| 113 | 77.0M |         rp[i] &= v; | 
| 114 | 77.0M |     } | 
| 115 |  |  | 
| 116 | 3.34M |     r->top = max; | 
| 117 | 3.34M |     r->flags |= BN_FLG_FIXED_TOP; | 
| 118 | 3.34M |     n0 = mont->n0[0]; | 
| 119 |  |  | 
| 120 |  |     /* | 
| 121 |  |      * Add multiples of |n| to |r| until R = 2^(nl * BN_BITS2) divides it. On | 
| 122 |  |      * input, we had |r| < |n| * R, so now |r| < 2 * |n| * R. Note that |r| | 
| 123 |  |      * includes |carry| which is stored separately. | 
| 124 |  |      */ | 
| 125 | 41.8M |     for (carry = 0, i = 0; i < nl; i++, rp++) { | 
| 126 | 38.5M |         v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2); | 
| 127 | 38.5M |         v = (v + carry + rp[nl]) & BN_MASK2; | 
| 128 | 38.5M |         carry |= (v != rp[nl]); | 
| 129 | 38.5M |         carry &= (v <= rp[nl]); | 
| 130 | 38.5M |         rp[nl] = v; | 
| 131 | 38.5M |     } | 
| 132 |  |  | 
| 133 | 3.34M |     if (bn_wexpand(ret, nl) == NULL) | 
| 134 | 0 |         return 0; | 
| 135 | 3.34M |     ret->top = nl; | 
| 136 | 3.34M |     ret->flags |= BN_FLG_FIXED_TOP; | 
| 137 | 3.34M |     ret->neg = r->neg; | 
| 138 |  |  | 
| 139 | 3.34M |     rp = ret->d; | 
| 140 |  |  | 
| 141 |  |     /* | 
| 142 |  |      * Shift |nl| words to divide by R. We have |ap| < 2 * |n|. Note that |ap| | 
| 143 |  |      * includes |carry| which is stored separately. | 
| 144 |  |      */ | 
| 145 | 3.34M |     ap = &(r->d[nl]); | 
| 146 |  |  | 
| 147 | 3.34M |     carry -= bn_sub_words(rp, ap, np, nl); | 
| 148 |  |     /* | 
| 149 |  |      * |carry| is -1 if |ap| - |np| underflowed or zero if it did not. Note | 
| 150 |  |      * |carry| cannot be 1. That would imply the subtraction did not fit in | 
| 151 |  |      * |nl| words, and we know at most one subtraction is needed. | 
| 152 |  |      */ | 
| 153 | 41.8M |     for (i = 0; i < nl; i++) { | 
| 154 | 38.5M |         rp[i] = (carry & ap[i]) | (~carry & rp[i]); | 
| 155 | 38.5M |         ap[i] = 0; | 
| 156 | 38.5M |     } | 
| 157 |  |  | 
| 158 | 3.34M |     return 1; | 
| 159 | 3.34M | } | 
| 160 |  | #endif                          /* MONT_WORD */ | 
| 161 |  |  | 
| 162 |  | int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, | 
| 163 |  |                        BN_CTX *ctx) | 
| 164 | 432k | { | 
| 165 | 432k |     int retn; | 
| 166 |  |  | 
| 167 | 432k |     retn = bn_from_mont_fixed_top(ret, a, mont, ctx); | 
| 168 | 432k |     bn_correct_top(ret); | 
| 169 | 432k |     bn_check_top(ret); | 
| 170 |  |  | 
| 171 | 432k |     return retn; | 
| 172 | 432k | } | 
| 173 |  |  | 
| 174 |  | int bn_from_mont_fixed_top(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, | 
| 175 |  |                            BN_CTX *ctx) | 
| 176 | 442k | { | 
| 177 | 442k |     int retn = 0; | 
| 178 | 442k | #ifdef MONT_WORD | 
| 179 | 442k |     BIGNUM *t; | 
| 180 |  |  | 
| 181 | 442k |     BN_CTX_start(ctx); | 
| 182 | 442k |     if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) { | 
| 183 | 442k |         retn = bn_from_montgomery_word(ret, t, mont); | 
| 184 | 442k |     } | 
| 185 | 442k |     BN_CTX_end(ctx); | 
| 186 |  | #else                           /* !MONT_WORD */ | 
| 187 |  |     BIGNUM *t1, *t2; | 
| 188 |  |  | 
| 189 |  |     BN_CTX_start(ctx); | 
| 190 |  |     t1 = BN_CTX_get(ctx); | 
| 191 |  |     t2 = BN_CTX_get(ctx); | 
| 192 |  |     if (t2 == NULL) | 
| 193 |  |         goto err; | 
| 194 |  |  | 
| 195 |  |     if (!BN_copy(t1, a)) | 
| 196 |  |         goto err; | 
| 197 |  |     BN_mask_bits(t1, mont->ri); | 
| 198 |  |  | 
| 199 |  |     if (!BN_mul(t2, t1, &mont->Ni, ctx)) | 
| 200 |  |         goto err; | 
| 201 |  |     BN_mask_bits(t2, mont->ri); | 
| 202 |  |  | 
| 203 |  |     if (!BN_mul(t1, t2, &mont->N, ctx)) | 
| 204 |  |         goto err; | 
| 205 |  |     if (!BN_add(t2, a, t1)) | 
| 206 |  |         goto err; | 
| 207 |  |     if (!BN_rshift(ret, t2, mont->ri)) | 
| 208 |  |         goto err; | 
| 209 |  |  | 
| 210 |  |     if (BN_ucmp(ret, &(mont->N)) >= 0) { | 
| 211 |  |         if (!BN_usub(ret, ret, &(mont->N))) | 
| 212 |  |             goto err; | 
| 213 |  |     } | 
| 214 |  |     retn = 1; | 
| 215 |  |     bn_check_top(ret); | 
| 216 |  |  err: | 
| 217 |  |     BN_CTX_end(ctx); | 
| 218 |  | #endif                          /* MONT_WORD */ | 
| 219 | 442k |     return retn; | 
| 220 | 442k | } | 
| 221 |  |  | 
| 222 |  | int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, | 
| 223 |  |                          BN_CTX *ctx) | 
| 224 | 260k | { | 
| 225 | 260k |     return bn_mul_mont_fixed_top(r, a, &(mont->RR), mont, ctx); | 
| 226 | 260k | } | 
| 227 |  |  | 
| 228 |  | BN_MONT_CTX *BN_MONT_CTX_new(void) | 
| 229 | 868k | { | 
| 230 | 868k |     BN_MONT_CTX *ret; | 
| 231 |  |  | 
| 232 | 868k |     if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { | 
| 233 | 0 |         ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); | 
| 234 | 0 |         return NULL; | 
| 235 | 0 |     } | 
| 236 |  |  | 
| 237 | 868k |     BN_MONT_CTX_init(ret); | 
| 238 | 868k |     ret->flags = BN_FLG_MALLOCED; | 
| 239 | 868k |     return ret; | 
| 240 | 868k | } | 
| 241 |  |  | 
| 242 |  | void BN_MONT_CTX_init(BN_MONT_CTX *ctx) | 
| 243 | 868k | { | 
| 244 | 868k |     ctx->ri = 0; | 
| 245 | 868k |     bn_init(&ctx->RR); | 
| 246 | 868k |     bn_init(&ctx->N); | 
| 247 | 868k |     bn_init(&ctx->Ni); | 
| 248 | 868k |     ctx->n0[0] = ctx->n0[1] = 0; | 
| 249 | 868k |     ctx->flags = 0; | 
| 250 | 868k | } | 
| 251 |  |  | 
| 252 |  | void BN_MONT_CTX_free(BN_MONT_CTX *mont) | 
| 253 | 2.77M | { | 
| 254 | 2.77M |     if (mont == NULL) | 
| 255 | 1.90M |         return; | 
| 256 | 868k |     BN_clear_free(&mont->RR); | 
| 257 | 868k |     BN_clear_free(&mont->N); | 
| 258 | 868k |     BN_clear_free(&mont->Ni); | 
| 259 | 868k |     if (mont->flags & BN_FLG_MALLOCED) | 
| 260 | 868k |         OPENSSL_free(mont); | 
| 261 | 868k | } | 
| 262 |  |  | 
| 263 |  | int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) | 
| 264 | 523k | { | 
| 265 | 523k |     int i, ret = 0; | 
| 266 | 523k |     BIGNUM *Ri, *R; | 
| 267 |  |  | 
| 268 | 523k |     if (BN_is_zero(mod)) | 
| 269 | 3 |         return 0; | 
| 270 |  |  | 
| 271 | 523k |     BN_CTX_start(ctx); | 
| 272 | 523k |     if ((Ri = BN_CTX_get(ctx)) == NULL) | 
| 273 | 0 |         goto err; | 
| 274 | 523k |     R = &(mont->RR);            /* grab RR as a temp */ | 
| 275 | 523k |     if (!BN_copy(&(mont->N), mod)) | 
| 276 | 0 |         goto err;               /* Set N */ | 
| 277 | 523k |     if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) | 
| 278 | 10.4k |         BN_set_flags(&(mont->N), BN_FLG_CONSTTIME); | 
| 279 | 523k |     mont->N.neg = 0; | 
| 280 |  |  | 
| 281 | 523k | #ifdef MONT_WORD | 
| 282 | 523k |     { | 
| 283 | 523k |         BIGNUM tmod; | 
| 284 | 523k |         BN_ULONG buf[2]; | 
| 285 |  |  | 
| 286 | 523k |         bn_init(&tmod); | 
| 287 | 523k |         tmod.d = buf; | 
| 288 | 523k |         tmod.dmax = 2; | 
| 289 | 523k |         tmod.neg = 0; | 
| 290 |  |  | 
| 291 | 523k |         if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) | 
| 292 | 10.4k |             BN_set_flags(&tmod, BN_FLG_CONSTTIME); | 
| 293 |  |  | 
| 294 | 523k |         mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; | 
| 295 |  |  | 
| 296 |  | # if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) | 
| 297 |  |         /* | 
| 298 |  |          * Only certain BN_BITS2<=32 platforms actually make use of n0[1], | 
| 299 |  |          * and we could use the #else case (with a shorter R value) for the | 
| 300 |  |          * others.  However, currently only the assembler files do know which | 
| 301 |  |          * is which. | 
| 302 |  |          */ | 
| 303 |  |  | 
| 304 |  |         BN_zero(R); | 
| 305 |  |         if (!(BN_set_bit(R, 2 * BN_BITS2))) | 
| 306 |  |             goto err; | 
| 307 |  |  | 
| 308 |  |         tmod.top = 0; | 
| 309 |  |         if ((buf[0] = mod->d[0])) | 
| 310 |  |             tmod.top = 1; | 
| 311 |  |         if ((buf[1] = mod->top > 1 ? mod->d[1] : 0)) | 
| 312 |  |             tmod.top = 2; | 
| 313 |  |  | 
| 314 |  |         if (BN_is_one(&tmod)) | 
| 315 |  |             BN_zero(Ri); | 
| 316 |  |         else if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) | 
| 317 |  |             goto err; | 
| 318 |  |         if (!BN_lshift(Ri, Ri, 2 * BN_BITS2)) | 
| 319 |  |             goto err;           /* R*Ri */ | 
| 320 |  |         if (!BN_is_zero(Ri)) { | 
| 321 |  |             if (!BN_sub_word(Ri, 1)) | 
| 322 |  |                 goto err; | 
| 323 |  |         } else {                /* if N mod word size == 1 */ | 
| 324 |  |  | 
| 325 |  |             if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL) | 
| 326 |  |                 goto err; | 
| 327 |  |             /* Ri-- (mod double word size) */ | 
| 328 |  |             Ri->neg = 0; | 
| 329 |  |             Ri->d[0] = BN_MASK2; | 
| 330 |  |             Ri->d[1] = BN_MASK2; | 
| 331 |  |             Ri->top = 2; | 
| 332 |  |         } | 
| 333 |  |         if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) | 
| 334 |  |             goto err; | 
| 335 |  |         /* | 
| 336 |  |          * Ni = (R*Ri-1)/N, keep only couple of least significant words: | 
| 337 |  |          */ | 
| 338 |  |         mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; | 
| 339 |  |         mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; | 
| 340 |  | # else | 
| 341 | 523k |         BN_zero(R); | 
| 342 | 523k |         if (!(BN_set_bit(R, BN_BITS2))) | 
| 343 | 0 |             goto err;           /* R */ | 
| 344 |  |  | 
| 345 | 523k |         buf[0] = mod->d[0];     /* tmod = N mod word size */ | 
| 346 | 523k |         buf[1] = 0; | 
| 347 | 523k |         tmod.top = buf[0] != 0 ? 1 : 0; | 
| 348 |  |         /* Ri = R^-1 mod N */ | 
| 349 | 523k |         if (BN_is_one(&tmod)) | 
| 350 | 57.7k |             BN_zero(Ri); | 
| 351 | 465k |         else if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) | 
| 352 | 3.00k |             goto err; | 
| 353 | 520k |         if (!BN_lshift(Ri, Ri, BN_BITS2)) | 
| 354 | 0 |             goto err;           /* R*Ri */ | 
| 355 | 520k |         if (!BN_is_zero(Ri)) { | 
| 356 | 462k |             if (!BN_sub_word(Ri, 1)) | 
| 357 | 0 |                 goto err; | 
| 358 | 462k |         } else {                /* if N mod word size == 1 */ | 
| 359 |  |  | 
| 360 | 57.7k |             if (!BN_set_word(Ri, BN_MASK2)) | 
| 361 | 0 |                 goto err;       /* Ri-- (mod word size) */ | 
| 362 | 57.7k |         } | 
| 363 | 520k |         if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) | 
| 364 | 0 |             goto err; | 
| 365 |  |         /* | 
| 366 |  |          * Ni = (R*Ri-1)/N, keep only least significant word: | 
| 367 |  |          */ | 
| 368 | 520k |         mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; | 
| 369 | 520k |         mont->n0[1] = 0; | 
| 370 | 520k | # endif | 
| 371 | 520k |     } | 
| 372 |  | #else                           /* !MONT_WORD */ | 
| 373 |  |     {                           /* bignum version */ | 
| 374 |  |         mont->ri = BN_num_bits(&mont->N); | 
| 375 |  |         BN_zero(R); | 
| 376 |  |         if (!BN_set_bit(R, mont->ri)) | 
| 377 |  |             goto err;           /* R = 2^ri */ | 
| 378 |  |         /* Ri = R^-1 mod N */ | 
| 379 |  |         if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL) | 
| 380 |  |             goto err; | 
| 381 |  |         if (!BN_lshift(Ri, Ri, mont->ri)) | 
| 382 |  |             goto err;           /* R*Ri */ | 
| 383 |  |         if (!BN_sub_word(Ri, 1)) | 
| 384 |  |             goto err; | 
| 385 |  |         /* | 
| 386 |  |          * Ni = (R*Ri-1) / N | 
| 387 |  |          */ | 
| 388 |  |         if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx)) | 
| 389 |  |             goto err; | 
| 390 |  |     } | 
| 391 |  | #endif | 
| 392 |  |  | 
| 393 |  |     /* setup RR for conversions */ | 
| 394 | 520k |     BN_zero(&(mont->RR)); | 
| 395 | 520k |     if (!BN_set_bit(&(mont->RR), mont->ri * 2)) | 
| 396 | 0 |         goto err; | 
| 397 | 520k |     if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) | 
| 398 | 0 |         goto err; | 
| 399 |  |  | 
| 400 | 670k |     for (i = mont->RR.top, ret = mont->N.top; i < ret; i++) | 
| 401 | 149k |         mont->RR.d[i] = 0; | 
| 402 | 520k |     mont->RR.top = ret; | 
| 403 | 520k |     mont->RR.flags |= BN_FLG_FIXED_TOP; | 
| 404 |  |  | 
| 405 | 520k |     ret = 1; | 
| 406 | 523k |  err: | 
| 407 | 523k |     BN_CTX_end(ctx); | 
| 408 | 523k |     return ret; | 
| 409 | 520k | } | 
| 410 |  |  | 
| 411 |  | BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) | 
| 412 | 344k | { | 
| 413 | 344k |     if (to == from) | 
| 414 | 0 |         return to; | 
| 415 |  |  | 
| 416 | 344k |     if (!BN_copy(&(to->RR), &(from->RR))) | 
| 417 | 0 |         return NULL; | 
| 418 | 344k |     if (!BN_copy(&(to->N), &(from->N))) | 
| 419 | 0 |         return NULL; | 
| 420 | 344k |     if (!BN_copy(&(to->Ni), &(from->Ni))) | 
| 421 | 0 |         return NULL; | 
| 422 | 344k |     to->ri = from->ri; | 
| 423 | 344k |     to->n0[0] = from->n0[0]; | 
| 424 | 344k |     to->n0[1] = from->n0[1]; | 
| 425 | 344k |     return to; | 
| 426 | 344k | } | 
| 427 |  |  | 
| 428 |  | BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock, | 
| 429 |  |                                     const BIGNUM *mod, BN_CTX *ctx) | 
| 430 | 20.0k | { | 
| 431 | 20.0k |     BN_MONT_CTX *ret; | 
| 432 |  |  | 
| 433 | 20.0k |     if (!CRYPTO_THREAD_read_lock(lock)) | 
| 434 | 0 |         return NULL; | 
| 435 | 20.0k |     ret = *pmont; | 
| 436 | 20.0k |     CRYPTO_THREAD_unlock(lock); | 
| 437 | 20.0k |     if (ret) | 
| 438 | 4.64k |         return ret; | 
| 439 |  |  | 
| 440 |  |     /* | 
| 441 |  |      * We don't want to serialize globally while doing our lazy-init math in | 
| 442 |  |      * BN_MONT_CTX_set. That punishes threads that are doing independent | 
| 443 |  |      * things. Instead, punish the case where more than one thread tries to | 
| 444 |  |      * lazy-init the same 'pmont', by having each do the lazy-init math work | 
| 445 |  |      * independently and only use the one from the thread that wins the race | 
| 446 |  |      * (the losers throw away the work they've done). | 
| 447 |  |      */ | 
| 448 | 15.3k |     ret = BN_MONT_CTX_new(); | 
| 449 | 15.3k |     if (ret == NULL) | 
| 450 | 0 |         return NULL; | 
| 451 | 15.3k |     if (!BN_MONT_CTX_set(ret, mod, ctx)) { | 
| 452 | 460 |         BN_MONT_CTX_free(ret); | 
| 453 | 460 |         return NULL; | 
| 454 | 460 |     } | 
| 455 |  |  | 
| 456 |  |     /* The locked compare-and-set, after the local work is done. */ | 
| 457 | 14.9k |     if (!CRYPTO_THREAD_write_lock(lock)) { | 
| 458 | 0 |         BN_MONT_CTX_free(ret); | 
| 459 | 0 |         return NULL; | 
| 460 | 0 |     } | 
| 461 |  |  | 
| 462 | 14.9k |     if (*pmont) { | 
| 463 | 0 |         BN_MONT_CTX_free(ret); | 
| 464 | 0 |         ret = *pmont; | 
| 465 | 0 |     } else | 
| 466 | 14.9k |         *pmont = ret; | 
| 467 | 14.9k |     CRYPTO_THREAD_unlock(lock); | 
| 468 | 14.9k |     return ret; | 
| 469 | 14.9k | } |