OpenCoverage

bn_ctx.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/bn/bn_ctx.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.-
3 *-
4 * Licensed under the OpenSSL license (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#include "internal/cryptlib.h"-
11#include "bn_lcl.h"-
12-
13/*--
14 * TODO list-
15 *-
16 * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and-
17 * check they can be safely removed.-
18 * - Check +1 and other ugliness in BN_from_montgomery()-
19 *-
20 * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an-
21 * appropriate 'block' size that will be honoured by bn_expand_internal() to-
22 * prevent piddly little reallocations. OTOH, profiling bignum expansions in-
23 * BN_CTX doesn't show this to be a big issue.-
24 */-
25-
26/* How many bignums are in each "pool item"; */-
27#define BN_CTX_POOL_SIZE 16-
28/* The stack frame info is resizing, set a first-time expansion size; */-
29#define BN_CTX_START_FRAMES 32-
30-
31/***********/-
32/* BN_POOL */-
33/***********/-
34-
35/* A bundle of bignums that can be linked with other bundles */-
36typedef struct bignum_pool_item {-
37 /* The bignum values */-
38 BIGNUM vals[BN_CTX_POOL_SIZE];-
39 /* Linked-list admin */-
40 struct bignum_pool_item *prev, *next;-
41} BN_POOL_ITEM;-
42/* A linked-list of bignums grouped in bundles */-
43typedef struct bignum_pool {-
44 /* Linked-list admin */-
45 BN_POOL_ITEM *head, *current, *tail;-
46 /* Stack depth and allocation size */-
47 unsigned used, size;-
48} BN_POOL;-
49static void BN_POOL_init(BN_POOL *);-
50static void BN_POOL_finish(BN_POOL *);-
51static BIGNUM *BN_POOL_get(BN_POOL *, int);-
52static void BN_POOL_release(BN_POOL *, unsigned int);-
53-
54/************/-
55/* BN_STACK */-
56/************/-
57-
58/* A wrapper to manage the "stack frames" */-
59typedef struct bignum_ctx_stack {-
60 /* Array of indexes into the bignum stack */-
61 unsigned int *indexes;-
62 /* Number of stack frames, and the size of the allocated array */-
63 unsigned int depth, size;-
64} BN_STACK;-
65static void BN_STACK_init(BN_STACK *);-
66static void BN_STACK_finish(BN_STACK *);-
67static int BN_STACK_push(BN_STACK *, unsigned int);-
68static unsigned int BN_STACK_pop(BN_STACK *);-
69-
70/**********/-
71/* BN_CTX */-
72/**********/-
73-
74/* The opaque BN_CTX type */-
75struct bignum_ctx {-
76 /* The bignum bundles */-
77 BN_POOL pool;-
78 /* The "stack frames", if you will */-
79 BN_STACK stack;-
80 /* The number of bignums currently assigned */-
81 unsigned int used;-
82 /* Depth of stack overflow */-
83 int err_stack;-
84 /* Block "gets" until an "end" (compatibility behaviour) */-
85 int too_many;-
86 /* Flags. */-
87 int flags;-
88};-
89-
90/* Enable this to find BN_CTX bugs */-
91#ifdef BN_CTX_DEBUG-
92static const char *ctxdbg_cur = NULL;-
93static void ctxdbg(BN_CTX *ctx)-
94{-
95 unsigned int bnidx = 0, fpidx = 0;-
96 BN_POOL_ITEM *item = ctx->pool.head;-
97 BN_STACK *stack = &ctx->stack;-
98 fprintf(stderr, "(%16p): ", ctx);-
99 while (bnidx < ctx->used) {-
100 fprintf(stderr, "%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);-
101 if (!(bnidx % BN_CTX_POOL_SIZE))-
102 item = item->next;-
103 }-
104 fprintf(stderr, "\n");-
105 bnidx = 0;-
106 fprintf(stderr, " : ");-
107 while (fpidx < stack->depth) {-
108 while (bnidx++ < stack->indexes[fpidx])-
109 fprintf(stderr, " ");-
110 fprintf(stderr, "^^^ ");-
111 bnidx++;-
112 fpidx++;-
113 }-
114 fprintf(stderr, "\n");-
115}-
116-
117# define CTXDBG_ENTRY(str, ctx) do { \-
118 ctxdbg_cur = (str); \-
119 fprintf(stderr,"Starting %s\n", ctxdbg_cur); \-
120 ctxdbg(ctx); \-
121 } while(0)-
122# define CTXDBG_EXIT(ctx) do { \-
123 fprintf(stderr,"Ending %s\n", ctxdbg_cur); \-
124 ctxdbg(ctx); \-
125 } while(0)-
126# define CTXDBG_RET(ctx,ret)-
127#else-
128# define CTXDBG_ENTRY(str, ctx)-
129# define CTXDBG_EXIT(ctx)-
130# define CTXDBG_RET(ctx,ret)-
131#endif-
132-
133-
134BN_CTX *BN_CTX_new(void)-
135{-
136 BN_CTX *ret;-
137-
138 if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
(ret = CRYPTO_...== ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 135934 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
0-135934
139 BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE);-
140 return NULL;
never executed: return ((void *)0) ;
0
141 }-
142 /* Initialise the structure */-
143 BN_POOL_init(&ret->pool);-
144 BN_STACK_init(&ret->stack);-
145 return ret;
executed 135934 times by 2 tests: return ret;
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
135934
146}-
147-
148BN_CTX *BN_CTX_secure_new(void)-
149{-
150 BN_CTX *ret = BN_CTX_new();-
151-
152 if (ret != NULL)
ret != ((void *)0)Description
TRUEevaluated 402 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEnever evaluated
0-402
153 ret->flags = BN_FLG_SECURE;
executed 402 times by 2 tests: ret->flags = 0x08;
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
402
154 return ret;
executed 402 times by 2 tests: return ret;
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
402
155}-
156-
157void BN_CTX_free(BN_CTX *ctx)-
158{-
159 if (ctx == NULL)
ctx == ((void *)0)Description
TRUEevaluated 551182 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 135934 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
135934-551182
160 return;
executed 551182 times by 2 tests: return;
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
551182
161#ifdef BN_CTX_DEBUG-
162 {-
163 BN_POOL_ITEM *pool = ctx->pool.head;-
164 fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n",-
165 ctx->stack.size, ctx->pool.size);-
166 fprintf(stderr, "dmaxs: ");-
167 while (pool) {-
168 unsigned loop = 0;-
169 while (loop < BN_CTX_POOL_SIZE)-
170 fprintf(stderr, "%02x ", pool->vals[loop++].dmax);-
171 pool = pool->next;-
172 }-
173 fprintf(stderr, "\n");-
174 }-
175#endif-
176 BN_STACK_finish(&ctx->stack);-
177 BN_POOL_finish(&ctx->pool);-
178 OPENSSL_free(ctx);-
179}
executed 135934 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
135934
180-
181void BN_CTX_start(BN_CTX *ctx)-
182{-
183 CTXDBG_ENTRY("BN_CTX_start", ctx);-
184 /* If we're already overflowing ... */-
185 if (ctx->err_stack || ctx->too_many)
ctx->err_stackDescription
TRUEnever evaluated
FALSEevaluated 74719294 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
ctx->too_manyDescription
TRUEnever evaluated
FALSEevaluated 74719294 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
0-74719294
186 ctx->err_stack++;
never executed: ctx->err_stack++;
0
187 /* (Try to) get a new frame pointer */-
188 else if (!BN_STACK_push(&ctx->stack, ctx->used)) {
!BN_STACK_push...ck, ctx->used)Description
TRUEnever evaluated
FALSEevaluated 74719294 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
0-74719294
189 BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES);-
190 ctx->err_stack++;-
191 }
never executed: end of block
0
192 CTXDBG_EXIT(ctx);-
193}
executed 74719294 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
74719294
194-
195void BN_CTX_end(BN_CTX *ctx)-
196{-
197 CTXDBG_ENTRY("BN_CTX_end", ctx);-
198 if (ctx->err_stack)
ctx->err_stackDescription
TRUEnever evaluated
FALSEevaluated 74719278 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
0-74719278
199 ctx->err_stack--;
never executed: ctx->err_stack--;
0
200 else {-
201 unsigned int fp = BN_STACK_pop(&ctx->stack);-
202 /* Does this stack frame have anything to release? */-
203 if (fp < ctx->used)
fp < ctx->usedDescription
TRUEevaluated 71593884 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 3125394 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
3125394-71593884
204 BN_POOL_release(&ctx->pool, ctx->used - fp);
executed 71593884 times by 2 tests: BN_POOL_release(&ctx->pool, ctx->used - fp);
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
71593884
205 ctx->used = fp;-
206 /* Unjam "too_many" in case "get" had failed */-
207 ctx->too_many = 0;-
208 }
executed 74719278 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
74719278
209 CTXDBG_EXIT(ctx);-
210}-
211-
212BIGNUM *BN_CTX_get(BN_CTX *ctx)-
213{-
214 BIGNUM *ret;-
215-
216 CTXDBG_ENTRY("BN_CTX_get", ctx);-
217 if (ctx->err_stack || ctx->too_many)
ctx->err_stackDescription
TRUEnever evaluated
FALSEevaluated 97054752 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
ctx->too_manyDescription
TRUEnever evaluated
FALSEevaluated 97054752 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
0-97054752
218 return NULL;
never executed: return ((void *)0) ;
0
219 if ((ret = BN_POOL_get(&ctx->pool, ctx->flags)) == NULL) {
(ret = BN_POOL...== ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 97054752 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
0-97054752
220 /*-
221 * Setting too_many prevents repeated "get" attempts from cluttering-
222 * the error stack.-
223 */-
224 ctx->too_many = 1;-
225 BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES);-
226 return NULL;
never executed: return ((void *)0) ;
0
227 }-
228 /* OK, make sure the returned bignum is "zero" */-
229 BN_zero(ret);-
230 ctx->used++;-
231 CTXDBG_RET(ctx, ret);-
232 return ret;
executed 97054752 times by 2 tests: return ret;
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
97054752
233}-
234-
235/************/-
236/* BN_STACK */-
237/************/-
238-
239static void BN_STACK_init(BN_STACK *st)-
240{-
241 st->indexes = NULL;-
242 st->depth = st->size = 0;-
243}
executed 135934 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
135934
244-
245static void BN_STACK_finish(BN_STACK *st)-
246{-
247 OPENSSL_free(st->indexes);-
248 st->indexes = NULL;-
249}
executed 135934 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
135934
250-
251-
252static int BN_STACK_push(BN_STACK *st, unsigned int idx)-
253{-
254 if (st->depth == st->size) {
st->depth == st->sizeDescription
TRUEevaluated 135647 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 74583647 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
135647-74583647
255 /* Need to expand */-
256 unsigned int newsize =-
257 st->size ? (st->size * 3 / 2) : BN_CTX_START_FRAMES;
st->sizeDescription
TRUEnever evaluated
FALSEevaluated 135647 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
0-135647
258 unsigned int *newitems;-
259 -
260 if ((newitems = OPENSSL_malloc(sizeof(*newitems) * newsize)) == NULL) {
(newitems = CR...== ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 135647 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
0-135647
261 BNerr(BN_F_BN_STACK_PUSH, ERR_R_MALLOC_FAILURE);-
262 return 0;
never executed: return 0;
0
263 }-
264 if (st->depth)
st->depthDescription
TRUEnever evaluated
FALSEevaluated 135647 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
0-135647
265 memcpy(newitems, st->indexes, sizeof(*newitems) * st->depth);
never executed: memcpy(newitems, st->indexes, sizeof(*newitems) * st->depth);
0
266 OPENSSL_free(st->indexes);-
267 st->indexes = newitems;-
268 st->size = newsize;-
269 }
executed 135647 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
135647
270 st->indexes[(st->depth)++] = idx;-
271 return 1;
executed 74719294 times by 2 tests: return 1;
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
74719294
272}-
273-
274static unsigned int BN_STACK_pop(BN_STACK *st)-
275{-
276 return st->indexes[--(st->depth)];
executed 74719278 times by 2 tests: return st->indexes[--(st->depth)];
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
74719278
277}-
278-
279/***********/-
280/* BN_POOL */-
281/***********/-
282-
283static void BN_POOL_init(BN_POOL *p)-
284{-
285 p->head = p->current = p->tail = NULL;-
286 p->used = p->size = 0;-
287}
executed 135934 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
135934
288-
289static void BN_POOL_finish(BN_POOL *p)-
290{-
291 unsigned int loop;-
292 BIGNUM *bn;-
293-
294 while (p->head) {
p->headDescription
TRUEevaluated 142688 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 135934 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
135934-142688
295 for (loop = 0, bn = p->head->vals; loop++ < BN_CTX_POOL_SIZE; bn++)
loop++ < 16Description
TRUEevaluated 2283008 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 142688 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
142688-2283008
296 if (bn->d)
bn->dDescription
TRUEevaluated 1303185 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 979823 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
979823-1303185
297 BN_clear_free(bn);
executed 1303185 times by 2 tests: BN_clear_free(bn);
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
1303185
298 p->current = p->head->next;-
299 OPENSSL_free(p->head);-
300 p->head = p->current;-
301 }
executed 142688 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
142688
302}
executed 135934 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
135934
303-
304-
305static BIGNUM *BN_POOL_get(BN_POOL *p, int flag)-
306{-
307 BIGNUM *bn;-
308 unsigned int loop;-
309-
310 /* Full; allocate a new pool item and link it in. */-
311 if (p->used == p->size) {
p->used == p->sizeDescription
TRUEevaluated 142688 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 96912064 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
142688-96912064
312 BN_POOL_ITEM *item;-
313 -
314 if ((item = OPENSSL_malloc(sizeof(*item))) == NULL) {
(item = CRYPTO...== ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 142688 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
0-142688
315 BNerr(BN_F_BN_POOL_GET, ERR_R_MALLOC_FAILURE);-
316 return NULL;
never executed: return ((void *)0) ;
0
317 }-
318 for (loop = 0, bn = item->vals; loop++ < BN_CTX_POOL_SIZE; bn++) {
loop++ < 16Description
TRUEevaluated 2283008 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 142688 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
142688-2283008
319 bn_init(bn);-
320 if ((flag & BN_FLG_SECURE) != 0)
(flag & 0x08) != 0Description
TRUEevaluated 6272 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 2276736 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
6272-2276736
321 BN_set_flags(bn, BN_FLG_SECURE);
executed 6272 times by 2 tests: BN_set_flags(bn, 0x08);
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
6272
322 }
executed 2283008 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
2283008
323 item->prev = p->tail;-
324 item->next = NULL;-
325-
326 if (p->head == NULL)
p->head == ((void *)0)Description
TRUEevaluated 135192 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 7496 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
7496-135192
327 p->head = p->current = p->tail = item;
executed 135192 times by 2 tests: p->head = p->current = p->tail = item;
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
135192
328 else {-
329 p->tail->next = item;-
330 p->tail = item;-
331 p->current = item;-
332 }
executed 7496 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
7496
333 p->size += BN_CTX_POOL_SIZE;-
334 p->used++;-
335 /* Return the first bignum from the new pool */-
336 return item->vals;
executed 142688 times by 2 tests: return item->vals;
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
142688
337 }-
338-
339 if (!p->used)
!p->usedDescription
TRUEevaluated 240365 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 96671699 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
240365-96671699
340 p->current = p->head;
executed 240365 times by 2 tests: p->current = p->head;
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
240365
341 else if ((p->used % BN_CTX_POOL_SIZE) == 0)
(p->used % 16) == 0Description
TRUEevaluated 3946415 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 92725284 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
3946415-92725284
342 p->current = p->current->next;
executed 3946415 times by 1 test: p->current = p->current->next;
Executed by:
  • libcrypto.so.1.1
3946415
343 return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
executed 96912064 times by 2 tests: return p->current->vals + ((p->used++) % 16);
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
96912064
344}-
345-
346static void BN_POOL_release(BN_POOL *p, unsigned int num)-
347{-
348 unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;-
349-
350 p->used -= num;-
351 while (num--) {
num--Description
TRUEevaluated 97054414 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 71593884 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
71593884-97054414
352 bn_check_top(p->current->vals + offset);-
353 if (offset == 0) {
offset == 0Description
TRUEevaluated 4329383 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 92725031 times by 2 tests
Evaluated by:
  • libcrypto.so.1.1
  • sm2_internal_test
4329383-92725031
354 offset = BN_CTX_POOL_SIZE - 1;-
355 p->current = p->current->prev;-
356 } else
executed 4329383 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
4329383
357 offset--;
executed 92725031 times by 2 tests: offset--;
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
92725031
358 }-
359}
executed 71593884 times by 2 tests: end of block
Executed by:
  • libcrypto.so.1.1
  • sm2_internal_test
71593884
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2