OpenCoverage

eng_table.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/engine/eng_table.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright 2001-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 <openssl/evp.h>-
12#include <openssl/lhash.h>-
13#include "eng_int.h"-
14-
15/* The type of the items in the table */-
16struct st_engine_pile {-
17 /* The 'nid' of this algorithm/mode */-
18 int nid;-
19 /* ENGINEs that implement this algorithm/mode. */-
20 STACK_OF(ENGINE) *sk;-
21 /* The default ENGINE to perform this algorithm/mode. */-
22 ENGINE *funct;-
23 /*-
24 * Zero if 'sk' is newer than the cached 'funct', non-zero otherwise-
25 */-
26 int uptodate;-
27};-
28-
29/* The type exposed in eng_int.h */-
30struct st_engine_table {-
31 LHASH_OF(ENGINE_PILE) piles;-
32}; /* ENGINE_TABLE */-
33-
34typedef struct st_engine_pile_doall {-
35 engine_table_doall_cb *cb;-
36 void *arg;-
37} ENGINE_PILE_DOALL;-
38-
39/* Global flags (ENGINE_TABLE_FLAG_***). */-
40static unsigned int table_flags = 0;-
41-
42/* API function manipulating 'table_flags' */-
43unsigned int ENGINE_get_table_flags(void)-
44{-
45 return table_flags;
never executed: return table_flags;
0
46}-
47-
48void ENGINE_set_table_flags(unsigned int flags)-
49{-
50 table_flags = flags;-
51}
never executed: end of block
0
52-
53/* Internal functions for the "piles" hash table */-
54static unsigned long engine_pile_hash(const ENGINE_PILE *c)-
55{-
56 return c->nid;
executed 20857 times by 1 test: return c->nid;
Executed by:
  • libcrypto.so.1.1
20857
57}-
58-
59static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)-
60{-
61 return a->nid - b->nid;
executed 14801 times by 1 test: return a->nid - b->nid;
Executed by:
  • libcrypto.so.1.1
14801
62}-
63-
64static int int_table_check(ENGINE_TABLE **t, int create)-
65{-
66 LHASH_OF(ENGINE_PILE) *lh;-
67-
68 if (*t)
*tDescription
TRUEevaluated 12049 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 1101 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
1101-12049
69 return 1;
executed 12049 times by 1 test: return 1;
Executed by:
  • libcrypto.so.1.1
12049
70 if (!create)
!createDescription
TRUEnever evaluated
FALSEevaluated 1101 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-1101
71 return 0;
never executed: return 0;
0
72 if ((lh = lh_ENGINE_PILE_new(engine_pile_hash, engine_pile_cmp)) == NULL)
(lh = lh_ENGIN...== ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 1101 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-1101
73 return 0;
never executed: return 0;
0
74 *t = (ENGINE_TABLE *)lh;-
75 return 1;
executed 1101 times by 1 test: return 1;
Executed by:
  • libcrypto.so.1.1
1101
76}-
77-
78/*-
79 * Privately exposed (via eng_int.h) functions for adding and/or removing-
80 * ENGINEs from the implementation table-
81 */-
82int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,-
83 ENGINE *e, const int *nids, int num_nids,-
84 int setdefault)-
85{-
86 int ret = 0, added = 0;-
87 ENGINE_PILE tmplate, *fnd;-
88 CRYPTO_THREAD_write_lock(global_engine_lock);-
89 if (!(*table))
!(*table)Description
TRUEevaluated 1101 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-1101
90 added = 1;
executed 1101 times by 1 test: added = 1;
Executed by:
  • libcrypto.so.1.1
1101
91 if (!int_table_check(table, 1))
!int_table_check(table, 1)Description
TRUEnever evaluated
FALSEevaluated 1101 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-1101
92 goto end;
never executed: goto end;
0
93 if (added)
addedDescription
TRUEevaluated 1101 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-1101
94 /* The cleanup callback needs to be added */-
95 engine_cleanup_add_first(cleanup);
executed 1101 times by 1 test: engine_cleanup_add_first(cleanup);
Executed by:
  • libcrypto.so.1.1
1101
96 while (num_nids--) {
num_nids--Description
TRUEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 1101 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
1101-2936
97 tmplate.nid = *nids;-
98 fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);-
99 if (!fnd) {
!fndDescription
TRUEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-2936
100 fnd = OPENSSL_malloc(sizeof(*fnd));-
101 if (fnd == NULL)
fnd == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-2936
102 goto end;
never executed: goto end;
0
103 fnd->uptodate = 1;-
104 fnd->nid = *nids;-
105 fnd->sk = sk_ENGINE_new_null();-
106 if (!fnd->sk) {
!fnd->skDescription
TRUEnever evaluated
FALSEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-2936
107 OPENSSL_free(fnd);-
108 goto end;
never executed: goto end;
0
109 }-
110 fnd->funct = NULL;-
111 (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);-
112 if (lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate) != fnd) {
lh_ENGINE_PILE...mplate) != fndDescription
TRUEnever evaluated
FALSEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-2936
113 sk_ENGINE_free(fnd->sk);-
114 OPENSSL_free(fnd);-
115 goto end;
never executed: goto end;
0
116 }-
117 }
executed 2936 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
2936
118 /* A registration shouldn't add duplicate entries */-
119 (void)sk_ENGINE_delete_ptr(fnd->sk, e);-
120 /*-
121 * if 'setdefault', this ENGINE goes to the head of the list-
122 */-
123 if (!sk_ENGINE_push(fnd->sk, e))
!sk_ENGINE_push(fnd->sk, e)Description
TRUEnever evaluated
FALSEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-2936
124 goto end;
never executed: goto end;
0
125 /* "touch" this ENGINE_PILE */-
126 fnd->uptodate = 0;-
127 if (setdefault) {
setdefaultDescription
TRUEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-2936
128 if (!engine_unlocked_init(e)) {
!engine_unlocked_init(e)Description
TRUEnever evaluated
FALSEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-2936
129 ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,-
130 ENGINE_R_INIT_FAILED);-
131 goto end;
never executed: goto end;
0
132 }-
133 if (fnd->funct)
fnd->functDescription
TRUEnever evaluated
FALSEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-2936
134 engine_unlocked_finish(fnd->funct, 0);
never executed: engine_unlocked_finish(fnd->funct, 0);
0
135 fnd->funct = e;-
136 fnd->uptodate = 1;-
137 }
executed 2936 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
2936
138 nids++;-
139 }
executed 2936 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
2936
140 ret = 1;-
141 end:
code before this statement executed 1101 times by 1 test: end:
Executed by:
  • libcrypto.so.1.1
1101
142 CRYPTO_THREAD_unlock(global_engine_lock);-
143 return ret;
executed 1101 times by 1 test: return ret;
Executed by:
  • libcrypto.so.1.1
1101
144}-
145-
146static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)-
147{-
148 int n;-
149 /* Iterate the 'c->sk' stack removing any occurrence of 'e' */-
150 while ((n = sk_ENGINE_find(pile->sk, e)) >= 0) {
(n = sk_ENGINE...->sk, e)) >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
151 (void)sk_ENGINE_delete(pile->sk, n);-
152 pile->uptodate = 0;-
153 }
never executed: end of block
0
154 if (pile->funct == e) {
pile->funct == eDescription
TRUEnever evaluated
FALSEnever evaluated
0
155 engine_unlocked_finish(e, 0);-
156 pile->funct = NULL;-
157 }
never executed: end of block
0
158}
never executed: end of block
0
159-
160IMPLEMENT_LHASH_DOALL_ARG(ENGINE_PILE, ENGINE);
never executed: end of block
0
161-
162void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)-
163{-
164 CRYPTO_THREAD_write_lock(global_engine_lock);-
165 if (int_table_check(table, 0))
int_table_check(table, 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
166 lh_ENGINE_PILE_doall_ENGINE(&(*table)->piles, int_unregister_cb, e);
never executed: lh_ENGINE_PILE_doall_ENGINE(&(*table)->piles, int_unregister_cb, e);
0
167 CRYPTO_THREAD_unlock(global_engine_lock);-
168}
never executed: end of block
0
169-
170static void int_cleanup_cb_doall(ENGINE_PILE *p)-
171{-
172 if (!p)
!pDescription
TRUEnever evaluated
FALSEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-2936
173 return;
never executed: return;
0
174 sk_ENGINE_free(p->sk);-
175 if (p->funct)
p->functDescription
TRUEevaluated 2936 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-2936
176 engine_unlocked_finish(p->funct, 0);
executed 2936 times by 1 test: engine_unlocked_finish(p->funct, 0);
Executed by:
  • libcrypto.so.1.1
2936
177 OPENSSL_free(p);-
178}
executed 2936 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
2936
179-
180void engine_table_cleanup(ENGINE_TABLE **table)-
181{-
182 CRYPTO_THREAD_write_lock(global_engine_lock);-
183 if (*table) {
*tableDescription
TRUEevaluated 1101 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-1101
184 lh_ENGINE_PILE_doall(&(*table)->piles, int_cleanup_cb_doall);-
185 lh_ENGINE_PILE_free(&(*table)->piles);-
186 *table = NULL;-
187 }
executed 1101 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
1101
188 CRYPTO_THREAD_unlock(global_engine_lock);-
189}
executed 1101 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
1101
190-
191/* return a functional reference for a given 'nid' */-
192#ifndef ENGINE_TABLE_DEBUG-
193ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)-
194#else-
195ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f,-
196 int l)-
197#endif-
198{-
199 ENGINE *ret = NULL;-
200 ENGINE_PILE tmplate, *fnd = NULL;-
201 int initres, loop = 0;-
202-
203 if (!(*table)) {
!(*table)Description
TRUEevaluated 4142606 times by 3 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
  • sm2_internal_test
FALSEevaluated 12049 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
12049-4142606
204#ifdef ENGINE_TABLE_DEBUG-
205 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "-
206 "registered!\n", f, l, nid);-
207#endif-
208 return NULL;
executed 4141226 times by 3 tests: return ((void *)0) ;
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
  • sm2_internal_test
4141226
209 }-
210 ERR_set_mark();-
211 CRYPTO_THREAD_write_lock(global_engine_lock);-
212 /*-
213 * Check again inside the lock otherwise we could race against cleanup-
214 * operations. But don't worry about a fprintf(stderr).-
215 */-
216 if (!int_table_check(table, 0))
!int_table_check(table, 0)Description
TRUEnever evaluated
FALSEevaluated 12049 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-12049
217 goto end;
never executed: goto end;
0
218 tmplate.nid = nid;-
219 fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);-
220 if (!fnd)
!fndDescription
TRUEevaluated 184 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 11865 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
184-11865
221 goto end;
executed 184 times by 1 test: goto end;
Executed by:
  • libcrypto.so.1.1
184
222 if (fnd->funct && engine_unlocked_init(fnd->funct)) {
fnd->functDescription
TRUEevaluated 11865 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
engine_unlocke...it(fnd->funct)Description
TRUEevaluated 11865 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-11865
223#ifdef ENGINE_TABLE_DEBUG-
224 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "-
225 "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);-
226#endif-
227 ret = fnd->funct;-
228 goto end;
executed 11865 times by 1 test: goto end;
Executed by:
  • libcrypto.so.1.1
11865
229 }-
230 if (fnd->uptodate) {
fnd->uptodateDescription
TRUEnever evaluated
FALSEnever evaluated
0
231 ret = fnd->funct;-
232 goto end;
never executed: goto end;
0
233 }-
234 trynext:
code before this statement never executed: trynext:
0
235 ret = sk_ENGINE_value(fnd->sk, loop++);-
236 if (!ret) {
!retDescription
TRUEnever evaluated
FALSEnever evaluated
0
237#ifdef ENGINE_TABLE_DEBUG-
238 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "-
239 "registered implementations would initialise\n", f, l, nid);-
240#endif-
241 goto end;
never executed: goto end;
0
242 }-
243 /* Try to initialise the ENGINE? */-
244 if ((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
(ret->funct_ref > 0)Description
TRUEnever evaluated
FALSEnever evaluated
!(table_flags ...ed int)0x0001)Description
TRUEnever evaluated
FALSEnever evaluated
0
245 initres = engine_unlocked_init(ret);
never executed: initres = engine_unlocked_init(ret);
0
246 else-
247 initres = 0;
never executed: initres = 0;
0
248 if (initres) {
initresDescription
TRUEnever evaluated
FALSEnever evaluated
0
249 /* Update 'funct' */-
250 if ((fnd->funct != ret) && engine_unlocked_init(ret)) {
(fnd->funct != ret)Description
TRUEnever evaluated
FALSEnever evaluated
engine_unlocked_init(ret)Description
TRUEnever evaluated
FALSEnever evaluated
0
251 /* If there was a previous default we release it. */-
252 if (fnd->funct)
fnd->functDescription
TRUEnever evaluated
FALSEnever evaluated
0
253 engine_unlocked_finish(fnd->funct, 0);
never executed: engine_unlocked_finish(fnd->funct, 0);
0
254 fnd->funct = ret;-
255#ifdef ENGINE_TABLE_DEBUG-
256 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "-
257 "setting default to '%s'\n", f, l, nid, ret->id);-
258#endif-
259 }
never executed: end of block
0
260#ifdef ENGINE_TABLE_DEBUG-
261 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "-
262 "newly initialised '%s'\n", f, l, nid, ret->id);-
263#endif-
264 goto end;
never executed: goto end;
0
265 }-
266 goto trynext;
never executed: goto trynext;
0
267 end:-
268 /*-
269 * If it failed, it is unlikely to succeed again until some future-
270 * registrations have taken place. In all cases, we cache.-
271 */-
272 if (fnd)
fndDescription
TRUEevaluated 11865 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 184 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
184-11865
273 fnd->uptodate = 1;
executed 11865 times by 1 test: fnd->uptodate = 1;
Executed by:
  • libcrypto.so.1.1
11865
274#ifdef ENGINE_TABLE_DEBUG-
275 if (ret)-
276 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "-
277 "ENGINE '%s'\n", f, l, nid, ret->id);-
278 else-
279 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "-
280 "'no matching ENGINE'\n", f, l, nid);-
281#endif-
282 CRYPTO_THREAD_unlock(global_engine_lock);-
283 /*-
284 * Whatever happened, any failed init()s are not failures in this-
285 * context, so clear our error state.-
286 */-
287 ERR_pop_to_mark();-
288 return ret;
executed 12049 times by 1 test: return ret;
Executed by:
  • libcrypto.so.1.1
12049
289}-
290-
291/* Table enumeration */-
292-
293static void int_dall(const ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)-
294{-
295 dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);-
296}
never executed: end of block
0
297-
298IMPLEMENT_LHASH_DOALL_ARG_CONST(ENGINE_PILE, ENGINE_PILE_DOALL);
never executed: end of block
0
299-
300void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,-
301 void *arg)-
302{-
303 ENGINE_PILE_DOALL dall;-
304 dall.cb = cb;-
305 dall.arg = arg;-
306 if (table)
tableDescription
TRUEnever evaluated
FALSEevaluated 9796 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-9796
307 lh_ENGINE_PILE_doall_ENGINE_PILE_DOALL(&table->piles, int_dall, &dall);
never executed: lh_ENGINE_PILE_doall_ENGINE_PILE_DOALL(&table->piles, int_dall, &dall);
0
308}
executed 9796 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
9796
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2