LCOV - code coverage report
Current view: top level - bn - bn_mont.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 140 144 97.2 %
Date: 2014-08-02 Functions: 9 9 100.0 %
Branches: 71 108 65.7 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/bn/bn_mont.c */
       2                 :            : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3                 :            :  * All rights reserved.
       4                 :            :  *
       5                 :            :  * This package is an SSL implementation written
       6                 :            :  * by Eric Young (eay@cryptsoft.com).
       7                 :            :  * The implementation was written so as to conform with Netscapes SSL.
       8                 :            :  * 
       9                 :            :  * This library is free for commercial and non-commercial use as long as
      10                 :            :  * the following conditions are aheared to.  The following conditions
      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
      13                 :            :  * included with this distribution is covered by the same copyright terms
      14                 :            :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15                 :            :  * 
      16                 :            :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17                 :            :  * the code are not to be removed.
      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.
      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.
      22                 :            :  * 
      23                 :            :  * Redistribution and use in source and binary forms, with or without
      24                 :            :  * modification, are permitted provided that the following conditions
      25                 :            :  * are met:
      26                 :            :  * 1. Redistributions of source code must retain the copyright
      27                 :            :  *    notice, this list of conditions and the following disclaimer.
      28                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      29                 :            :  *    notice, this list of conditions and the following disclaimer in the
      30                 :            :  *    documentation and/or other materials provided with the distribution.
      31                 :            :  * 3. All advertising materials mentioning features or use of this software
      32                 :            :  *    must display the following acknowledgement:
      33                 :            :  *    "This product includes cryptographic software written by
      34                 :            :  *     Eric Young (eay@cryptsoft.com)"
      35                 :            :  *    The word 'cryptographic' can be left out if the rouines from the library
      36                 :            :  *    being used are not cryptographic related :-).
      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:
      39                 :            :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40                 :            :  * 
      41                 :            :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42                 :            :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44                 :            :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45                 :            :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46                 :            :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47                 :            :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      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
      51                 :            :  * SUCH DAMAGE.
      52                 :            :  * 
      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
      55                 :            :  * copied and put under another distribution licence
      56                 :            :  * [including the GNU Public Licence.]
      57                 :            :  */
      58                 :            : /* ====================================================================
      59                 :            :  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
      60                 :            :  *
      61                 :            :  * Redistribution and use in source and binary forms, with or without
      62                 :            :  * modification, are permitted provided that the following conditions
      63                 :            :  * are met:
      64                 :            :  *
      65                 :            :  * 1. Redistributions of source code must retain the above copyright
      66                 :            :  *    notice, this list of conditions and the following disclaimer. 
      67                 :            :  *
      68                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      69                 :            :  *    notice, this list of conditions and the following disclaimer in
      70                 :            :  *    the documentation and/or other materials provided with the
      71                 :            :  *    distribution.
      72                 :            :  *
      73                 :            :  * 3. All advertising materials mentioning features or use of this
      74                 :            :  *    software must display the following acknowledgment:
      75                 :            :  *    "This product includes software developed by the OpenSSL Project
      76                 :            :  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
      77                 :            :  *
      78                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      79                 :            :  *    endorse or promote products derived from this software without
      80                 :            :  *    prior written permission. For written permission, please contact
      81                 :            :  *    openssl-core@openssl.org.
      82                 :            :  *
      83                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      84                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      85                 :            :  *    permission of the OpenSSL Project.
      86                 :            :  *
      87                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      88                 :            :  *    acknowledgment:
      89                 :            :  *    "This product includes software developed by the OpenSSL Project
      90                 :            :  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
      91                 :            :  *
      92                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      93                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      94                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      95                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      96                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      97                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      98                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      99                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     100                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     101                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     102                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     103                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
     104                 :            :  * ====================================================================
     105                 :            :  *
     106                 :            :  * This product includes cryptographic software written by Eric Young
     107                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
     108                 :            :  * Hudson (tjh@cryptsoft.com).
     109                 :            :  *
     110                 :            :  */
     111                 :            : 
     112                 :            : /*
     113                 :            :  * Details about Montgomery multiplication algorithms can be found at
     114                 :            :  * http://security.ece.orst.edu/publications.html, e.g.
     115                 :            :  * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
     116                 :            :  * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
     117                 :            :  */
     118                 :            : 
     119                 :            : #define OPENSSL_FIPSAPI
     120                 :            : 
     121                 :            : #include <stdio.h>
     122                 :            : #include "cryptlib.h"
     123                 :            : #include "bn_lcl.h"
     124                 :            : 
     125                 :            : #define MONT_WORD /* use the faster word-based algorithm */
     126                 :            : 
     127                 :            : #ifdef MONT_WORD
     128                 :            : static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
     129                 :            : #endif
     130                 :            : 
     131                 :    2724090 : int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
     132                 :            :                           BN_MONT_CTX *mont, BN_CTX *ctx)
     133                 :            :         {
     134                 :            :         BIGNUM *tmp;
     135                 :    2724090 :         int ret=0;
     136                 :            : #if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
     137                 :    2724090 :         int num = mont->N.top;
     138                 :            : 
     139 [ +  + ][ +  + ]:    2724090 :         if (num>1 && a->top==num && b->top==num)
                 [ +  + ]
     140                 :            :                 {
     141 [ +  + ][ +  - ]:    2695302 :                 if (bn_wexpand(r,num) == NULL) return(0);
     142         [ +  - ]:    2695302 :                 if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num))
     143                 :            :                         {
     144                 :    2695302 :                         r->neg = a->neg^b->neg;
     145                 :    2695302 :                         r->top = num;
     146 [ +  - ][ +  + ]:    2697261 :                         bn_correct_top(r);
                 [ +  - ]
     147                 :            :                         return(1);
     148                 :            :                         }
     149                 :            :                 }
     150                 :            : #endif
     151                 :            : 
     152                 :      28788 :         BN_CTX_start(ctx);
     153                 :      28788 :         tmp = BN_CTX_get(ctx);
     154         [ +  - ]:      28788 :         if (tmp == NULL) goto err;
     155                 :            : 
     156                 :            :         bn_check_top(tmp);
     157         [ +  + ]:      28788 :         if (a == b)
     158                 :            :                 {
     159         [ +  - ]:      10187 :                 if (!BN_sqr(tmp,a,ctx)) goto err;
     160                 :            :                 }
     161                 :            :         else
     162                 :            :                 {
     163         [ +  - ]:      18601 :                 if (!BN_mul(tmp,a,b,ctx)) goto err;
     164                 :            :                 }
     165                 :            :         /* reduce from aRR to aR */
     166                 :            : #ifdef MONT_WORD
     167         [ +  - ]:      28788 :         if (!BN_from_montgomery_word(r,tmp,mont)) goto err;
     168                 :            : #else
     169                 :            :         if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
     170                 :            : #endif
     171                 :            :         bn_check_top(r);
     172                 :      28788 :         ret=1;
     173                 :            : err:
     174                 :      28788 :         BN_CTX_end(ctx);
     175                 :      28788 :         return(ret);
     176                 :            :         }
     177                 :            : 
     178                 :            : #ifdef MONT_WORD
     179                 :      37371 : static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
     180                 :            :         {
     181                 :            :         BIGNUM *n;
     182                 :            :         BN_ULONG *ap,*np,*rp,n0,v,carry;
     183                 :            :         int nl,max,i;
     184                 :            : 
     185                 :      37371 :         n= &(mont->N);
     186                 :      37371 :         nl=n->top;
     187         [ -  + ]:      37371 :         if (nl == 0) { ret->top=0; return(1); }
     188                 :            : 
     189                 :      37371 :         max=(2*nl); /* carry is stored separately */
     190 [ +  + ][ +  - ]:      37371 :         if (bn_wexpand(r,max) == NULL) return(0);
     191                 :            : 
     192                 :      37371 :         r->neg^=n->neg;
     193                 :      37371 :         np=n->d;
     194                 :      37371 :         rp=r->d;
     195                 :            : 
     196                 :            :         /* clear the top words of T */
     197                 :            : #if 1
     198         [ +  + ]:     256014 :         for (i=r->top; i<max; i++) /* memset? XXX */
     199                 :     218643 :                 rp[i]=0;
     200                 :            : #else
     201                 :            :         memset(&(rp[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 
     202                 :            : #endif
     203                 :            : 
     204                 :      37371 :         r->top=max;
     205                 :      37371 :         n0=mont->n0[0];
     206                 :            : 
     207                 :            : #ifdef BN_COUNT
     208                 :            :         fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl);
     209                 :            : #endif
     210         [ +  + ]:     245871 :         for (carry=0, i=0; i<nl; i++, rp++)
     211                 :            :                 {
     212                 :            : #ifdef __TANDEM
     213                 :            :                 {
     214                 :            :                    long long t1;
     215                 :            :                    long long t2;
     216                 :            :                    long long t3;
     217                 :            :                    t1 = rp[0] * (n0 & 0177777);
     218                 :            :                    t2 = 037777600000l;
     219                 :            :                    t2 = n0 & t2;
     220                 :            :                    t3 = rp[0] & 0177777;
     221                 :            :                    t2 = (t3 * t2) & BN_MASK2;
     222                 :            :                    t1 = t1 + t2;
     223                 :            :                    v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
     224                 :            :                 }
     225                 :            : #else
     226                 :     208500 :                 v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
     227                 :            : #endif
     228                 :     208500 :                 v = (v+carry+rp[nl])&BN_MASK2;
     229                 :     208500 :                 carry |= (v != rp[nl]);
     230                 :     208500 :                 carry &= (v <= rp[nl]);
     231                 :     208500 :                 rp[nl]=v;
     232                 :            :                 }
     233                 :            : 
     234 [ +  + ][ +  - ]:      37371 :         if (bn_wexpand(ret,nl) == NULL) return(0);
     235                 :      37371 :         ret->top=nl;
     236                 :      37371 :         ret->neg=r->neg;
     237                 :            : 
     238                 :      37371 :         rp=ret->d;
     239                 :      37371 :         ap=&(r->d[nl]);
     240                 :            : 
     241                 :            : #define BRANCH_FREE 1
     242                 :            : #if BRANCH_FREE
     243                 :            :         {
     244                 :            :         BN_ULONG *nrp;
     245                 :            :         size_t m;
     246                 :            : 
     247                 :      37371 :         v=bn_sub_words(rp,ap,np,nl)-carry;
     248                 :            :         /* if subtraction result is real, then
     249                 :            :          * trick unconditional memcpy below to perform in-place
     250                 :            :          * "refresh" instead of actual copy. */
     251                 :      37371 :         m=(0-(size_t)v);
     252                 :      37371 :         nrp=(BN_ULONG *)(((PTR_SIZE_INT)rp&~m)|((PTR_SIZE_INT)ap&m));
     253                 :            : 
     254         [ +  + ]:      63890 :         for (i=0,nl-=4; i<nl; i+=4)
     255                 :            :                 {
     256                 :            :                 BN_ULONG t1,t2,t3,t4;
     257                 :            :                 
     258                 :      26519 :                 t1=nrp[i+0];
     259                 :      26519 :                 t2=nrp[i+1];
     260                 :      26519 :                 t3=nrp[i+2];    ap[i+0]=0;
     261                 :      26519 :                 t4=nrp[i+3];    ap[i+1]=0;
     262                 :      26519 :                 rp[i+0]=t1;     ap[i+2]=0;
     263                 :      26519 :                 rp[i+1]=t2;     ap[i+3]=0;
     264                 :      26519 :                 rp[i+2]=t3;
     265                 :      26519 :                 rp[i+3]=t4;
     266                 :            :                 }
     267         [ +  + ]:     139795 :         for (nl+=4; i<nl; i++)
     268                 :     102424 :                 rp[i]=nrp[i], ap[i]=0;
     269                 :            :         }
     270                 :            : #else
     271                 :            :         if (bn_sub_words (rp,ap,np,nl)-carry)
     272                 :            :                 memcpy(rp,ap,nl*sizeof(BN_ULONG));
     273                 :            : #endif
     274 [ +  - ][ +  - ]:     454371 :         bn_correct_top(r);
                 [ +  + ]
     275 [ +  - ][ +  + ]:      80935 :         bn_correct_top(ret);
                 [ +  + ]
     276                 :            :         bn_check_top(ret);
     277                 :            : 
     278                 :            :         return(1);
     279                 :            :         }
     280                 :            : #endif  /* MONT_WORD */
     281                 :            : 
     282                 :       8583 : int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
     283                 :            :              BN_CTX *ctx)
     284                 :            :         {
     285                 :       8583 :         int retn=0;
     286                 :            : #ifdef MONT_WORD
     287                 :            :         BIGNUM *t;
     288                 :            : 
     289                 :       8583 :         BN_CTX_start(ctx);
     290 [ +  - ][ +  - ]:       8583 :         if ((t = BN_CTX_get(ctx)) && BN_copy(t,a))
     291                 :       8583 :                 retn = BN_from_montgomery_word(ret,t,mont);
     292                 :       8583 :         BN_CTX_end(ctx);
     293                 :            : #else /* !MONT_WORD */
     294                 :            :         BIGNUM *t1,*t2;
     295                 :            : 
     296                 :            :         BN_CTX_start(ctx);
     297                 :            :         t1 = BN_CTX_get(ctx);
     298                 :            :         t2 = BN_CTX_get(ctx);
     299                 :            :         if (t1 == NULL || t2 == NULL) goto err;
     300                 :            :         
     301                 :            :         if (!BN_copy(t1,a)) goto err;
     302                 :            :         BN_mask_bits(t1,mont->ri);
     303                 :            : 
     304                 :            :         if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err;
     305                 :            :         BN_mask_bits(t2,mont->ri);
     306                 :            : 
     307                 :            :         if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
     308                 :            :         if (!BN_add(t2,a,t1)) goto err;
     309                 :            :         if (!BN_rshift(ret,t2,mont->ri)) goto err;
     310                 :            : 
     311                 :            :         if (BN_ucmp(ret, &(mont->N)) >= 0)
     312                 :            :                 {
     313                 :            :                 if (!BN_usub(ret,ret,&(mont->N))) goto err;
     314                 :            :                 }
     315                 :            :         retn=1;
     316                 :            :         bn_check_top(ret);
     317                 :            :  err:
     318                 :            :         BN_CTX_end(ctx);
     319                 :            : #endif /* MONT_WORD */
     320                 :       8583 :         return(retn);
     321                 :            :         }
     322                 :            : 
     323                 :       9885 : BN_MONT_CTX *BN_MONT_CTX_new(void)
     324                 :            :         {
     325                 :            :         BN_MONT_CTX *ret;
     326                 :            : 
     327         [ +  - ]:       9885 :         if ((ret=(BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL)
     328                 :            :                 return(NULL);
     329                 :            : 
     330                 :       9885 :         BN_MONT_CTX_init(ret);
     331                 :       9885 :         ret->flags=BN_FLG_MALLOCED;
     332                 :       9885 :         return(ret);
     333                 :            :         }
     334                 :            : 
     335                 :       9885 : void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
     336                 :            :         {
     337                 :       9885 :         ctx->ri=0;
     338                 :       9885 :         BN_init(&(ctx->RR));
     339                 :       9885 :         BN_init(&(ctx->N));
     340                 :       9885 :         BN_init(&(ctx->Ni));
     341                 :       9885 :         ctx->n0[0] = ctx->n0[1] = 0;
     342                 :       9885 :         ctx->flags=0;
     343                 :       9885 :         }
     344                 :            : 
     345                 :       9884 : void BN_MONT_CTX_free(BN_MONT_CTX *mont)
     346                 :            :         {
     347         [ +  - ]:       9884 :         if(mont == NULL)
     348                 :       9884 :             return;
     349                 :            : 
     350                 :       9884 :         BN_free(&(mont->RR));
     351                 :       9884 :         BN_free(&(mont->N));
     352                 :       9884 :         BN_free(&(mont->Ni));
     353         [ +  - ]:       9884 :         if (mont->flags & BN_FLG_MALLOCED)
     354                 :       9884 :                 OPENSSL_free(mont);
     355                 :            :         }
     356                 :            : 
     357                 :       9800 : int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
     358                 :            :         {
     359                 :       9800 :         int ret = 0;
     360                 :            :         BIGNUM *Ri,*R;
     361                 :            : 
     362                 :       9800 :         BN_CTX_start(ctx);
     363         [ +  - ]:       9800 :         if((Ri = BN_CTX_get(ctx)) == NULL) goto err;
     364                 :       9800 :         R= &(mont->RR);                                  /* grab RR as a temp */
     365         [ +  - ]:       9800 :         if (!BN_copy(&(mont->N),mod)) goto err;          /* Set N */
     366                 :       9800 :         mont->N.neg = 0;
     367                 :            : 
     368                 :            : #ifdef MONT_WORD
     369                 :            :                 {
     370                 :            :                 BIGNUM tmod;
     371                 :            :                 BN_ULONG buf[2];
     372                 :            : 
     373                 :       9800 :                 BN_init(&tmod);
     374                 :       9800 :                 tmod.d=buf;
     375                 :       9800 :                 tmod.dmax=2;
     376                 :       9800 :                 tmod.neg=0;
     377                 :            : 
     378                 :       9800 :                 mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
     379                 :            : 
     380                 :            : #if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
     381                 :            :                 /* Only certain BN_BITS2<=32 platforms actually make use of
     382                 :            :                  * n0[1], and we could use the #else case (with a shorter R
     383                 :            :                  * value) for the others.  However, currently only the assembler
     384                 :            :                  * files do know which is which. */
     385                 :            : 
     386                 :            :                 BN_zero(R);
     387                 :            :                 if (!(BN_set_bit(R,2*BN_BITS2))) goto err;
     388                 :            : 
     389                 :            :                                                                 tmod.top=0;
     390                 :            :                 if ((buf[0] = mod->d[0]))                    tmod.top=1;
     391                 :            :                 if ((buf[1] = mod->top>1 ? mod->d[1] : 0))     tmod.top=2;
     392                 :            : 
     393                 :            :                 if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
     394                 :            :                         goto err;
     395                 :            :                 if (!BN_lshift(Ri,Ri,2*BN_BITS2)) goto err; /* R*Ri */
     396                 :            :                 if (!BN_is_zero(Ri))
     397                 :            :                         {
     398                 :            :                         if (!BN_sub_word(Ri,1)) goto err;
     399                 :            :                         }
     400                 :            :                 else /* if N mod word size == 1 */
     401                 :            :                         {
     402                 :            :                         if (bn_expand(Ri,(int)sizeof(BN_ULONG)*2) == NULL)
     403                 :            :                                 goto err;
     404                 :            :                         /* Ri-- (mod double word size) */
     405                 :            :                         Ri->neg=0;
     406                 :            :                         Ri->d[0]=BN_MASK2;
     407                 :            :                         Ri->d[1]=BN_MASK2;
     408                 :            :                         Ri->top=2;
     409                 :            :                         }
     410                 :            :                 if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
     411                 :            :                 /* Ni = (R*Ri-1)/N,
     412                 :            :                  * keep only couple of least significant words: */
     413                 :            :                 mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
     414                 :            :                 mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
     415                 :            : #else
     416                 :       9800 :                 BN_zero(R);
     417         [ +  - ]:       9800 :                 if (!(BN_set_bit(R,BN_BITS2))) goto err;        /* R */
     418                 :            : 
     419                 :       9800 :                 buf[0]=mod->d[0]; /* tmod = N mod word size */
     420                 :       9800 :                 buf[1]=0;
     421                 :       9800 :                 tmod.top = buf[0] != 0 ? 1 : 0;
     422                 :            :                                                         /* Ri = R^-1 mod N*/
     423         [ +  - ]:       9800 :                 if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
     424                 :            :                         goto err;
     425         [ +  - ]:       9800 :                 if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */
     426         [ +  + ]:       9800 :                 if (!BN_is_zero(Ri))
     427                 :            :                         {
     428         [ +  - ]:       9788 :                         if (!BN_sub_word(Ri,1)) goto err;
     429                 :            :                         }
     430                 :            :                 else /* if N mod word size == 1 */
     431                 :            :                         {
     432         [ +  - ]:         12 :                         if (!BN_set_word(Ri,BN_MASK2)) goto err;  /* Ri-- (mod word size) */
     433                 :            :                         }
     434         [ +  - ]:       9800 :                 if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
     435                 :            :                 /* Ni = (R*Ri-1)/N,
     436                 :            :                  * keep only least significant word: */
     437         [ +  - ]:       9800 :                 mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
     438                 :       9800 :                 mont->n0[1] = 0;
     439                 :            : #endif
     440                 :            :                 }
     441                 :            : #else /* !MONT_WORD */
     442                 :            :                 { /* bignum version */
     443                 :            :                 mont->ri=BN_num_bits(&mont->N);
     444                 :            :                 BN_zero(R);
     445                 :            :                 if (!BN_set_bit(R,mont->ri)) goto err;  /* R = 2^ri */
     446                 :            :                                                         /* Ri = R^-1 mod N*/
     447                 :            :                 if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL)
     448                 :            :                         goto err;
     449                 :            :                 if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */
     450                 :            :                 if (!BN_sub_word(Ri,1)) goto err;
     451                 :            :                                                         /* Ni = (R*Ri-1) / N */
     452                 :            :                 if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err;
     453                 :            :                 }
     454                 :            : #endif
     455                 :            : 
     456                 :            :         /* setup RR for conversions */
     457                 :       9800 :         BN_zero(&(mont->RR));
     458         [ +  - ]:       9800 :         if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
     459         [ +  - ]:       9800 :         if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err;
     460                 :            : 
     461                 :       9800 :         ret = 1;
     462                 :            : err:
     463                 :       9800 :         BN_CTX_end(ctx);
     464                 :       9800 :         return ret;
     465                 :            :         }
     466                 :            : 
     467                 :         89 : BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
     468                 :            :         {
     469         [ +  - ]:         89 :         if (to == from) return(to);
     470                 :            : 
     471         [ +  - ]:         89 :         if (!BN_copy(&(to->RR),&(from->RR))) return NULL;
     472         [ +  - ]:         89 :         if (!BN_copy(&(to->N),&(from->N))) return NULL;
     473         [ +  - ]:         89 :         if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
     474                 :         89 :         to->ri=from->ri;
     475                 :         89 :         to->n0[0]=from->n0[0];
     476                 :         89 :         to->n0[1]=from->n0[1];
     477                 :         89 :         return(to);
     478                 :            :         }
     479                 :            : 
     480                 :       7687 : BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
     481                 :            :                                         const BIGNUM *mod, BN_CTX *ctx)
     482                 :            :         {
     483                 :            :         BN_MONT_CTX *ret;
     484                 :            : 
     485                 :       7687 :         CRYPTO_r_lock(lock);
     486                 :       7687 :         ret = *pmont;
     487                 :       7687 :         CRYPTO_r_unlock(lock);
     488         [ +  + ]:       7687 :         if (ret)
     489                 :            :                 return ret;
     490                 :            : 
     491                 :            :         /* We don't want to serialise globally while doing our lazy-init math in
     492                 :            :          * BN_MONT_CTX_set. That punishes threads that are doing independent
     493                 :            :          * things. Instead, punish the case where more than one thread tries to
     494                 :            :          * lazy-init the same 'pmont', by having each do the lazy-init math work
     495                 :            :          * independently and only use the one from the thread that wins the race
     496                 :            :          * (the losers throw away the work they've done). */
     497                 :       6606 :         ret = BN_MONT_CTX_new();
     498         [ +  - ]:       6606 :         if (!ret)
     499                 :            :                 return NULL;
     500         [ -  + ]:       6606 :         if (!BN_MONT_CTX_set(ret, mod, ctx))
     501                 :            :                 {
     502                 :          0 :                 BN_MONT_CTX_free(ret);
     503                 :          0 :                 return NULL;
     504                 :            :                 }
     505                 :            : 
     506                 :            :         /* The locked compare-and-set, after the local work is done. */
     507                 :       6606 :         CRYPTO_w_lock(lock);
     508         [ -  + ]:       6606 :         if (*pmont)
     509                 :            :                 {
     510                 :          0 :                 BN_MONT_CTX_free(ret);
     511                 :          0 :                 ret = *pmont;
     512                 :            :                 }
     513                 :            :         else
     514                 :       6606 :                 *pmont = ret;
     515                 :       6606 :         CRYPTO_w_unlock(lock);
     516                 :       6606 :         return ret;
     517                 :            :         }

Generated by: LCOV version 1.9