LCOV - code coverage report
Current view: top level - bn - bn_ctx.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 101 133 75.9 %
Date: 2014-08-02 Functions: 13 16 81.2 %
Branches: 40 60 66.7 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/bn/bn_ctx.c */
       2                 :            : /* Written by Ulf Moeller for the OpenSSL project. */
       3                 :            : /* ====================================================================
       4                 :            :  * Copyright (c) 1998-2004 The OpenSSL Project.  All rights reserved.
       5                 :            :  *
       6                 :            :  * Redistribution and use in source and binary forms, with or without
       7                 :            :  * modification, are permitted provided that the following conditions
       8                 :            :  * are met:
       9                 :            :  *
      10                 :            :  * 1. Redistributions of source code must retain the above copyright
      11                 :            :  *    notice, this list of conditions and the following disclaimer. 
      12                 :            :  *
      13                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      14                 :            :  *    notice, this list of conditions and the following disclaimer in
      15                 :            :  *    the documentation and/or other materials provided with the
      16                 :            :  *    distribution.
      17                 :            :  *
      18                 :            :  * 3. All advertising materials mentioning features or use of this
      19                 :            :  *    software must display the following acknowledgment:
      20                 :            :  *    "This product includes software developed by the OpenSSL Project
      21                 :            :  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
      22                 :            :  *
      23                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      24                 :            :  *    endorse or promote products derived from this software without
      25                 :            :  *    prior written permission. For written permission, please contact
      26                 :            :  *    openssl-core@openssl.org.
      27                 :            :  *
      28                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      29                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      30                 :            :  *    permission of the OpenSSL Project.
      31                 :            :  *
      32                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      33                 :            :  *    acknowledgment:
      34                 :            :  *    "This product includes software developed by the OpenSSL Project
      35                 :            :  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
      36                 :            :  *
      37                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      38                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      39                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      40                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      41                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      42                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      43                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      44                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      45                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      46                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      47                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      48                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      49                 :            :  * ====================================================================
      50                 :            :  *
      51                 :            :  * This product includes cryptographic software written by Eric Young
      52                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
      53                 :            :  * Hudson (tjh@cryptsoft.com).
      54                 :            :  *
      55                 :            :  */
      56                 :            : 
      57                 :            : #if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG)
      58                 :            : #ifndef NDEBUG
      59                 :            : #define NDEBUG
      60                 :            : #endif
      61                 :            : #endif
      62                 :            : 
      63                 :            : #define OPENSSL_FIPSAPI
      64                 :            : 
      65                 :            : #include <stdio.h>
      66                 :            : #include <assert.h>
      67                 :            : 
      68                 :            : #include "cryptlib.h"
      69                 :            : #include "bn_lcl.h"
      70                 :            : 
      71                 :            : /* TODO list
      72                 :            :  *
      73                 :            :  * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
      74                 :            :  * check they can be safely removed.
      75                 :            :  *  - Check +1 and other ugliness in BN_from_montgomery()
      76                 :            :  *
      77                 :            :  * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
      78                 :            :  * appropriate 'block' size that will be honoured by bn_expand_internal() to
      79                 :            :  * prevent piddly little reallocations. OTOH, profiling bignum expansions in
      80                 :            :  * BN_CTX doesn't show this to be a big issue.
      81                 :            :  */
      82                 :            : 
      83                 :            : /* How many bignums are in each "pool item"; */
      84                 :            : #define BN_CTX_POOL_SIZE        16
      85                 :            : /* The stack frame info is resizing, set a first-time expansion size; */
      86                 :            : #define BN_CTX_START_FRAMES     32
      87                 :            : 
      88                 :            : /***********/
      89                 :            : /* BN_POOL */
      90                 :            : /***********/
      91                 :            : 
      92                 :            : /* A bundle of bignums that can be linked with other bundles */
      93                 :            : typedef struct bignum_pool_item
      94                 :            :         {
      95                 :            :         /* The bignum values */
      96                 :            :         BIGNUM vals[BN_CTX_POOL_SIZE];
      97                 :            :         /* Linked-list admin */
      98                 :            :         struct bignum_pool_item *prev, *next;
      99                 :            :         } BN_POOL_ITEM;
     100                 :            : /* A linked-list of bignums grouped in bundles */
     101                 :            : typedef struct bignum_pool
     102                 :            :         {
     103                 :            :         /* Linked-list admin */
     104                 :            :         BN_POOL_ITEM *head, *current, *tail;
     105                 :            :         /* Stack depth and allocation size */
     106                 :            :         unsigned used, size;
     107                 :            :         } BN_POOL;
     108                 :            : static void             BN_POOL_init(BN_POOL *);
     109                 :            : static void             BN_POOL_finish(BN_POOL *);
     110                 :            : #ifndef OPENSSL_NO_DEPRECATED
     111                 :            : static void             BN_POOL_reset(BN_POOL *);
     112                 :            : #endif
     113                 :            : static BIGNUM *         BN_POOL_get(BN_POOL *);
     114                 :            : static void             BN_POOL_release(BN_POOL *, unsigned int);
     115                 :            : 
     116                 :            : /************/
     117                 :            : /* BN_STACK */
     118                 :            : /************/
     119                 :            : 
     120                 :            : /* A wrapper to manage the "stack frames" */
     121                 :            : typedef struct bignum_ctx_stack
     122                 :            :         {
     123                 :            :         /* Array of indexes into the bignum stack */
     124                 :            :         unsigned int *indexes;
     125                 :            :         /* Number of stack frames, and the size of the allocated array */
     126                 :            :         unsigned int depth, size;
     127                 :            :         } BN_STACK;
     128                 :            : static void             BN_STACK_init(BN_STACK *);
     129                 :            : static void             BN_STACK_finish(BN_STACK *);
     130                 :            : #ifndef OPENSSL_NO_DEPRECATED
     131                 :            : static void             BN_STACK_reset(BN_STACK *);
     132                 :            : #endif
     133                 :            : static int              BN_STACK_push(BN_STACK *, unsigned int);
     134                 :            : static unsigned int     BN_STACK_pop(BN_STACK *);
     135                 :            : 
     136                 :            : /**********/
     137                 :            : /* BN_CTX */
     138                 :            : /**********/
     139                 :            : 
     140                 :            : /* The opaque BN_CTX type */
     141                 :            : struct bignum_ctx
     142                 :            :         {
     143                 :            :         /* The bignum bundles */
     144                 :            :         BN_POOL pool;
     145                 :            :         /* The "stack frames", if you will */
     146                 :            :         BN_STACK stack;
     147                 :            :         /* The number of bignums currently assigned */
     148                 :            :         unsigned int used;
     149                 :            :         /* Depth of stack overflow */
     150                 :            :         int err_stack;
     151                 :            :         /* Block "gets" until an "end" (compatibility behaviour) */
     152                 :            :         int too_many;
     153                 :            :         };
     154                 :            : 
     155                 :            : /* Enable this to find BN_CTX bugs */
     156                 :            : #ifdef BN_CTX_DEBUG
     157                 :            : static const char *ctxdbg_cur = NULL;
     158                 :            : static void ctxdbg(BN_CTX *ctx)
     159                 :            :         {
     160                 :            :         unsigned int bnidx = 0, fpidx = 0;
     161                 :            :         BN_POOL_ITEM *item = ctx->pool.head;
     162                 :            :         BN_STACK *stack = &ctx->stack;
     163                 :            :         fprintf(stderr,"(%08x): ", (unsigned int)ctx);
     164                 :            :         while(bnidx < ctx->used)
     165                 :            :                 {
     166                 :            :                 fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
     167                 :            :                 if(!(bnidx % BN_CTX_POOL_SIZE))
     168                 :            :                         item = item->next;
     169                 :            :                 }
     170                 :            :         fprintf(stderr,"\n");
     171                 :            :         bnidx = 0;
     172                 :            :         fprintf(stderr,"          : ");
     173                 :            :         while(fpidx < stack->depth)
     174                 :            :                 {
     175                 :            :                 while(bnidx++ < stack->indexes[fpidx])
     176                 :            :                         fprintf(stderr,"    ");
     177                 :            :                 fprintf(stderr,"^^^ ");
     178                 :            :                 bnidx++;
     179                 :            :                 fpidx++;
     180                 :            :                 }
     181                 :            :         fprintf(stderr,"\n");
     182                 :            :         }
     183                 :            : #define CTXDBG_ENTRY(str, ctx)  do { \
     184                 :            :                                 ctxdbg_cur = (str); \
     185                 :            :                                 fprintf(stderr,"Starting %s\n", ctxdbg_cur); \
     186                 :            :                                 ctxdbg(ctx); \
     187                 :            :                                 } while(0)
     188                 :            : #define CTXDBG_EXIT(ctx)        do { \
     189                 :            :                                 fprintf(stderr,"Ending %s\n", ctxdbg_cur); \
     190                 :            :                                 ctxdbg(ctx); \
     191                 :            :                                 } while(0)
     192                 :            : #define CTXDBG_RET(ctx,ret)
     193                 :            : #else
     194                 :            : #define CTXDBG_ENTRY(str, ctx)
     195                 :            : #define CTXDBG_EXIT(ctx)
     196                 :            : #define CTXDBG_RET(ctx,ret)
     197                 :            : #endif
     198                 :            : 
     199                 :            : /* This function is an evil legacy and should not be used. This implementation
     200                 :            :  * is WYSIWYG, though I've done my best. */
     201                 :            : #ifndef OPENSSL_NO_DEPRECATED
     202                 :          0 : void BN_CTX_init(BN_CTX *ctx)
     203                 :            :         {
     204                 :            :         /* Assume the caller obtained the context via BN_CTX_new() and so is
     205                 :            :          * trying to reset it for use. Nothing else makes sense, least of all
     206                 :            :          * binary compatibility from a time when they could declare a static
     207                 :            :          * variable. */
     208                 :          0 :         BN_POOL_reset(&ctx->pool);
     209                 :          0 :         BN_STACK_reset(&ctx->stack);
     210                 :          0 :         ctx->used = 0;
     211                 :          0 :         ctx->err_stack = 0;
     212                 :          0 :         ctx->too_many = 0;
     213                 :          0 :         }
     214                 :            : #endif
     215                 :            : 
     216                 :     135657 : BN_CTX *BN_CTX_new(void)
     217                 :            :         {
     218                 :     135657 :         BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
     219         [ -  + ]:     135657 :         if(!ret)
     220                 :            :                 {
     221                 :          0 :                 BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
     222                 :          0 :                 return NULL;
     223                 :            :                 }
     224                 :            :         /* Initialise the structure */
     225                 :     135657 :         BN_POOL_init(&ret->pool);
     226                 :     135657 :         BN_STACK_init(&ret->stack);
     227                 :     135657 :         ret->used = 0;
     228                 :     135657 :         ret->err_stack = 0;
     229                 :     135657 :         ret->too_many = 0;
     230                 :     135657 :         return ret;
     231                 :            :         }
     232                 :            : 
     233                 :     135657 : void BN_CTX_free(BN_CTX *ctx)
     234                 :            :         {
     235         [ +  - ]:     135657 :         if (ctx == NULL)
     236                 :     135657 :                 return;
     237                 :            : #ifdef BN_CTX_DEBUG
     238                 :            :         {
     239                 :            :         BN_POOL_ITEM *pool = ctx->pool.head;
     240                 :            :         fprintf(stderr,"BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
     241                 :            :                 ctx->stack.size, ctx->pool.size);
     242                 :            :         fprintf(stderr,"dmaxs: ");
     243                 :            :         while(pool) {
     244                 :            :                 unsigned loop = 0;
     245                 :            :                 while(loop < BN_CTX_POOL_SIZE)
     246                 :            :                         fprintf(stderr,"%02x ", pool->vals[loop++].dmax);
     247                 :            :                 pool = pool->next;
     248                 :            :         }
     249                 :            :         fprintf(stderr,"\n");
     250                 :            :         }
     251                 :            : #endif
     252                 :     135657 :         BN_STACK_finish(&ctx->stack);
     253                 :     135657 :         BN_POOL_finish(&ctx->pool);
     254                 :     135657 :         OPENSSL_free(ctx);
     255                 :            :         }
     256                 :            : 
     257                 :   10899887 : void BN_CTX_start(BN_CTX *ctx)
     258                 :            :         {
     259                 :            :         CTXDBG_ENTRY("BN_CTX_start", ctx);
     260                 :            :         /* If we're already overflowing ... */
     261 [ +  - ][ -  + ]:   10899887 :         if(ctx->err_stack || ctx->too_many)
     262                 :          0 :                 ctx->err_stack++;
     263                 :            :         /* (Try to) get a new frame pointer */
     264         [ -  + ]:   10899887 :         else if(!BN_STACK_push(&ctx->stack, ctx->used))
     265                 :            :                 {
     266                 :          0 :                 BNerr(BN_F_BN_CTX_START,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
     267                 :          0 :                 ctx->err_stack++;
     268                 :            :                 }
     269                 :            :         CTXDBG_EXIT(ctx);
     270                 :   10899887 :         }
     271                 :            : 
     272                 :   10899887 : void BN_CTX_end(BN_CTX *ctx)
     273                 :            :         {
     274                 :            :         CTXDBG_ENTRY("BN_CTX_end", ctx);
     275         [ -  + ]:   10899887 :         if(ctx->err_stack)
     276                 :          0 :                 ctx->err_stack--;
     277                 :            :         else
     278                 :            :                 {
     279                 :   10899887 :                 unsigned int fp = BN_STACK_pop(&ctx->stack);
     280                 :            :                 /* Does this stack frame have anything to release? */
     281         [ +  + ]:   10899887 :                 if(fp < ctx->used)
     282                 :    9859268 :                         BN_POOL_release(&ctx->pool, ctx->used - fp);
     283                 :   10899887 :                 ctx->used = fp;
     284                 :            :                 /* Unjam "too_many" in case "get" had failed */
     285                 :   10899887 :                 ctx->too_many = 0;
     286                 :            :                 }
     287                 :            :         CTXDBG_EXIT(ctx);
     288                 :   10899887 :         }
     289                 :            : 
     290                 :   13542095 : BIGNUM *BN_CTX_get(BN_CTX *ctx)
     291                 :            :         {
     292                 :            :         BIGNUM *ret;
     293                 :            :         CTXDBG_ENTRY("BN_CTX_get", ctx);
     294 [ +  - ][ +  - ]:   13542095 :         if(ctx->err_stack || ctx->too_many) return NULL;
     295         [ -  + ]:   13542095 :         if((ret = BN_POOL_get(&ctx->pool)) == NULL)
     296                 :            :                 {
     297                 :            :                 /* Setting too_many prevents repeated "get" attempts from
     298                 :            :                  * cluttering the error stack. */
     299                 :          0 :                 ctx->too_many = 1;
     300                 :          0 :                 BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
     301                 :          0 :                 return NULL;
     302                 :            :                 }
     303                 :            :         /* OK, make sure the returned bignum is "zero" */
     304                 :   13542095 :         BN_zero(ret);
     305                 :   13542095 :         ctx->used++;
     306                 :            :         CTXDBG_RET(ctx, ret);
     307                 :   13542095 :         return ret;
     308                 :            :         }
     309                 :            : 
     310                 :            : /************/
     311                 :            : /* BN_STACK */
     312                 :            : /************/
     313                 :            : 
     314                 :     135657 : static void BN_STACK_init(BN_STACK *st)
     315                 :            :         {
     316                 :     135657 :         st->indexes = NULL;
     317                 :     135657 :         st->depth = st->size = 0;
     318                 :     135657 :         }
     319                 :            : 
     320                 :     271314 : static void BN_STACK_finish(BN_STACK *st)
     321                 :            :         {
     322         [ +  + ]:     135657 :         if(st->size) OPENSSL_free(st->indexes);
     323                 :     135657 :         }
     324                 :            : 
     325                 :            : #ifndef OPENSSL_NO_DEPRECATED
     326                 :          0 : static void BN_STACK_reset(BN_STACK *st)
     327                 :            :         {
     328                 :          0 :         st->depth = 0;
     329                 :          0 :         }
     330                 :            : #endif
     331                 :            : 
     332                 :   10899887 : static int BN_STACK_push(BN_STACK *st, unsigned int idx)
     333                 :            :         {
     334         [ +  + ]:   10899887 :         if(st->depth == st->size)
     335                 :            :                 /* Need to expand */
     336                 :            :                 {
     337                 :     134134 :                 unsigned int newsize = (st->size ?
     338         [ -  + ]:     134134 :                                 (st->size * 3 / 2) : BN_CTX_START_FRAMES);
     339                 :     134134 :                 unsigned int *newitems = OPENSSL_malloc(newsize *
     340                 :            :                                                 sizeof(unsigned int));
     341         [ +  - ]:     134134 :                 if(!newitems) return 0;
     342         [ -  + ]:     134134 :                 if(st->depth)
     343                 :          0 :                         memcpy(newitems, st->indexes, st->depth *
     344                 :            :                                                 sizeof(unsigned int));
     345         [ -  + ]:     134134 :                 if(st->size) OPENSSL_free(st->indexes);
     346                 :     134134 :                 st->indexes = newitems;
     347                 :     134134 :                 st->size = newsize;
     348                 :            :                 }
     349                 :   10899887 :         st->indexes[(st->depth)++] = idx;
     350                 :   10899887 :         return 1;
     351                 :            :         }
     352                 :            : 
     353                 :   10899887 : static unsigned int BN_STACK_pop(BN_STACK *st)
     354                 :            :         {
     355                 :   10899887 :         return st->indexes[--(st->depth)];
     356                 :            :         }
     357                 :            : 
     358                 :            : /***********/
     359                 :            : /* BN_POOL */
     360                 :            : /***********/
     361                 :            : 
     362                 :     135657 : static void BN_POOL_init(BN_POOL *p)
     363                 :            :         {
     364                 :     135657 :         p->head = p->current = p->tail = NULL;
     365                 :     135657 :         p->used = p->size = 0;
     366                 :     135657 :         }
     367                 :            : 
     368                 :     271314 : static void BN_POOL_finish(BN_POOL *p)
     369                 :            :         {
     370         [ +  + ]:     271384 :         while(p->head)
     371                 :            :                 {
     372                 :     135727 :                 unsigned int loop = 0;
     373                 :     135727 :                 BIGNUM *bn = p->head->vals;
     374         [ +  + ]:    2307359 :                 while(loop++ < BN_CTX_POOL_SIZE)
     375                 :            :                         {
     376         [ +  + ]:    2171632 :                         if(bn->d) BN_clear_free(bn);
     377                 :    2171632 :                         bn++;
     378                 :            :                         }
     379                 :     135727 :                 p->current = p->head->next;
     380                 :     135727 :                 OPENSSL_free(p->head);
     381                 :     135727 :                 p->head = p->current;
     382                 :            :                 }
     383                 :     135657 :         }
     384                 :            : 
     385                 :            : #ifndef OPENSSL_NO_DEPRECATED
     386                 :          0 : static void BN_POOL_reset(BN_POOL *p)
     387                 :            :         {
     388                 :          0 :         BN_POOL_ITEM *item = p->head;
     389         [ #  # ]:          0 :         while(item)
     390                 :            :                 {
     391                 :          0 :                 unsigned int loop = 0;
     392                 :          0 :                 BIGNUM *bn = item->vals;
     393         [ #  # ]:          0 :                 while(loop++ < BN_CTX_POOL_SIZE)
     394                 :            :                         {
     395         [ #  # ]:          0 :                         if(bn->d) BN_clear(bn);
     396                 :          0 :                         bn++;
     397                 :            :                         }
     398                 :          0 :                 item = item->next;
     399                 :            :                 }
     400                 :          0 :         p->current = p->head;
     401                 :          0 :         p->used = 0;
     402                 :          0 :         }
     403                 :            : #endif
     404                 :            : 
     405                 :   13542095 : static BIGNUM *BN_POOL_get(BN_POOL *p)
     406                 :            :         {
     407         [ +  + ]:   13542095 :         if(p->used == p->size)
     408                 :            :                 {
     409                 :            :                 BIGNUM *bn;
     410                 :     135727 :                 unsigned int loop = 0;
     411                 :     135727 :                 BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM));
     412         [ +  - ]:     135727 :                 if(!item) return NULL;
     413                 :            :                 /* Initialise the structure */
     414                 :     135727 :                 bn = item->vals;
     415         [ +  + ]:    2307359 :                 while(loop++ < BN_CTX_POOL_SIZE)
     416                 :    2171632 :                         BN_init(bn++);
     417                 :     135727 :                 item->prev = p->tail;
     418                 :     135727 :                 item->next = NULL;
     419                 :            :                 /* Link it in */
     420         [ +  + ]:     135727 :                 if(!p->head)
     421                 :     134134 :                         p->head = p->current = p->tail = item;
     422                 :            :                 else
     423                 :            :                         {
     424                 :       1593 :                         p->tail->next = item;
     425                 :       1593 :                         p->tail = item;
     426                 :       1593 :                         p->current = item;
     427                 :            :                         }
     428                 :     135727 :                 p->size += BN_CTX_POOL_SIZE;
     429                 :     135727 :                 p->used++;
     430                 :            :                 /* Return the first bignum from the new pool */
     431                 :     135727 :                 return item->vals;
     432                 :            :                 }
     433         [ +  + ]:   13406368 :         if(!p->used)
     434                 :      81087 :                 p->current = p->head;
     435         [ +  + ]:   13325281 :         else if((p->used % BN_CTX_POOL_SIZE) == 0)
     436                 :      13056 :                 p->current = p->current->next;
     437                 :   13406368 :         return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
     438                 :            :         }
     439                 :            : 
     440                 :   19718536 : static void BN_POOL_release(BN_POOL *p, unsigned int num)
     441                 :            :         {
     442                 :    9859268 :         unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
     443                 :    9859268 :         p->used -= num;
     444         [ +  + ]:   23401363 :         while(num--)
     445                 :            :                 {
     446                 :            :                 bn_check_top(p->current->vals + offset);
     447         [ +  + ]:   13542095 :                 if(!offset)
     448                 :            :                         {
     449                 :     229870 :                         offset = BN_CTX_POOL_SIZE - 1;
     450                 :     229870 :                         p->current = p->current->prev;
     451                 :            :                         }
     452                 :            :                 else
     453                 :   13542095 :                         offset--;
     454                 :            :                 }
     455                 :    9859268 :         }
     456                 :            : 

Generated by: LCOV version 1.9