File: | lib/crypto-backend.c |
Location: | line 90, column 3 |
Description: | Dereference of null pointer |
1 | /* | ||
2 | * Copyright (C) 2008, 2010-2012 Free Software Foundation, Inc. | ||
3 | * | ||
4 | * Author: Nikos Mavrogiannopoulos | ||
5 | * | ||
6 | * This file is part of GnuTLS. | ||
7 | * | ||
8 | * The GnuTLS is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU Lesser General Public License | ||
10 | * as published by the Free Software Foundation; either version 3 of | ||
11 | * the License, or (at your option) any later version. | ||
12 | * | ||
13 | * This library is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * Lesser General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU Lesser General Public License | ||
19 | * along with this program. If not, see <http://www.gnu.org/licenses/> | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <gnutls_errors.h> | ||
24 | #include <gnutls_int.h> | ||
25 | #include <gnutls/crypto.h> | ||
26 | #include <crypto-backend.h> | ||
27 | #include <crypto.h> | ||
28 | #include <gnutls_mpi.h> | ||
29 | #include <gnutls_pk.h> | ||
30 | #include <random.h> | ||
31 | #include <gnutls_cipher_int.h> | ||
32 | |||
33 | /* default values for priorities */ | ||
34 | int crypto_mac_prio = INT_MAX2147483647; | ||
35 | int crypto_digest_prio = INT_MAX2147483647; | ||
36 | int crypto_cipher_prio = INT_MAX2147483647; | ||
37 | |||
38 | typedef struct algo_list | ||
39 | { | ||
40 | int algorithm; | ||
41 | int priority; | ||
42 | const void *alg_data; | ||
43 | struct algo_list *next; | ||
44 | } algo_list; | ||
45 | |||
46 | #define cipher_listalgo_list algo_list | ||
47 | #define mac_listalgo_list algo_list | ||
48 | #define digest_listalgo_list algo_list | ||
49 | |||
50 | static int | ||
51 | _algo_register (algo_list * al, int algorithm, int priority, const void *s) | ||
52 | { | ||
53 | algo_list *cl; | ||
54 | algo_list *last_cl = al; | ||
55 | |||
56 | /* look if there is any cipher with lowest priority. In that case do not add. | ||
57 | */ | ||
58 | cl = al; | ||
59 | while (cl && cl->alg_data) | ||
| |||
| |||
60 | { | ||
61 | if (cl->algorithm == algorithm) | ||
62 | { | ||
63 | if (cl->priority < priority) | ||
64 | { | ||
65 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "crypto-backend.c",65); } while(0);; | ||
66 | return GNUTLS_E_CRYPTO_ALREADY_REGISTERED-209; | ||
67 | } | ||
68 | else | ||
69 | { | ||
70 | /* the current has higher priority -> overwrite */ | ||
71 | cl->algorithm = algorithm; | ||
72 | cl->priority = priority; | ||
73 | cl->alg_data = s; | ||
74 | return 0; | ||
75 | } | ||
76 | } | ||
77 | cl = cl->next; | ||
78 | if (cl) | ||
79 | last_cl = cl; | ||
80 | } | ||
81 | |||
82 | cl = gnutls_calloc (1, sizeof (cipher_listalgo_list)); | ||
83 | |||
84 | if (cl == NULL((void*)0)) | ||
| |||
85 | { | ||
86 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "crypto-backend.c",86); } while(0);; | ||
87 | return GNUTLS_E_MEMORY_ERROR-25; | ||
88 | } | ||
89 | |||
90 | last_cl->algorithm = algorithm; | ||
| |||
91 | last_cl->priority = priority; | ||
92 | last_cl->alg_data = s; | ||
93 | last_cl->next = cl; | ||
94 | |||
95 | return 0; | ||
96 | |||
97 | } | ||
98 | |||
99 | static const void * | ||
100 | _get_algo (algo_list * al, int algo) | ||
101 | { | ||
102 | cipher_listalgo_list *cl; | ||
103 | |||
104 | /* look if there is any cipher with lowest priority. In that case do not add. | ||
105 | */ | ||
106 | cl = al; | ||
107 | while (cl && cl->alg_data) | ||
108 | { | ||
109 | if (cl->algorithm == algo) | ||
110 | { | ||
111 | return cl->alg_data; | ||
112 | } | ||
113 | cl = cl->next; | ||
114 | } | ||
115 | |||
116 | return NULL((void*)0); | ||
117 | } | ||
118 | |||
119 | static cipher_listalgo_list glob_cl = { GNUTLS_CIPHER_NULL, 0, NULL((void*)0), NULL((void*)0) }; | ||
120 | static mac_listalgo_list glob_ml = { GNUTLS_MAC_NULL, 0, NULL((void*)0), NULL((void*)0) }; | ||
121 | static digest_listalgo_list glob_dl = { GNUTLS_MAC_NULL, 0, NULL((void*)0), NULL((void*)0) }; | ||
122 | |||
123 | static void | ||
124 | _deregister (algo_list * cl) | ||
125 | { | ||
126 | algo_list *next; | ||
127 | |||
128 | next = cl->next; | ||
129 | cl->next = NULL((void*)0); | ||
130 | cl = next; | ||
131 | |||
132 | while (cl) | ||
133 | { | ||
134 | next = cl->next; | ||
135 | gnutls_free (cl); | ||
136 | cl = next; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | void | ||
141 | _gnutls_crypto_deregister (void) | ||
142 | { | ||
143 | _deregister (&glob_cl); | ||
144 | _deregister (&glob_ml); | ||
145 | _deregister (&glob_dl); | ||
146 | } | ||
147 | |||
148 | /*- | ||
149 | * gnutls_crypto_single_cipher_register: | ||
150 | * @algorithm: is the gnutls algorithm identifier | ||
151 | * @priority: is the priority of the algorithm | ||
152 | * @s: is a structure holding new cipher's data | ||
153 | * | ||
154 | * This function will register a cipher algorithm to be used by | ||
155 | * gnutls. Any algorithm registered will override the included | ||
156 | * algorithms and by convention kernel implemented algorithms have | ||
157 | * priority of 90 and CPU-assisted of 80. The algorithm with the lowest priority will be | ||
158 | * used by gnutls. | ||
159 | * | ||
160 | * This function should be called before gnutls_global_init(). | ||
161 | * | ||
162 | * For simplicity you can use the convenience | ||
163 | * gnutls_crypto_single_cipher_register() macro. | ||
164 | * | ||
165 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. | ||
166 | * | ||
167 | * Since: 2.6.0 | ||
168 | -*/ | ||
169 | int | ||
170 | gnutls_crypto_single_cipher_register (gnutls_cipher_algorithm_t algorithm, | ||
171 | int priority, | ||
172 | const gnutls_crypto_cipher_st * s) | ||
173 | { | ||
174 | return _algo_register (&glob_cl, algorithm, priority, s); | ||
175 | } | ||
176 | |||
177 | const gnutls_crypto_cipher_st * | ||
178 | _gnutls_get_crypto_cipher (gnutls_cipher_algorithm_t algo) | ||
179 | { | ||
180 | return _get_algo (&glob_cl, algo); | ||
181 | } | ||
182 | |||
183 | /*- | ||
184 | * gnutls_crypto_rnd_register: | ||
185 | * @priority: is the priority of the generator | ||
186 | * @s: is a structure holding new generator's data | ||
187 | * | ||
188 | * This function will register a random generator to be used by | ||
189 | * gnutls. Any generator registered will override the included | ||
190 | * generator and by convention kernel implemented generators have | ||
191 | * priority of 90 and CPU-assisted of 80. The generator with the lowest priority will be | ||
192 | * used by gnutls. | ||
193 | * | ||
194 | * This function should be called before gnutls_global_init(). | ||
195 | * | ||
196 | * For simplicity you can use the convenience | ||
197 | * gnutls_crypto_rnd_register() macro. | ||
198 | * | ||
199 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. | ||
200 | * | ||
201 | * Since: 2.6.0 | ||
202 | -*/ | ||
203 | int | ||
204 | gnutls_crypto_rnd_register (int priority, | ||
205 | const gnutls_crypto_rnd_st * s) | ||
206 | { | ||
207 | if (crypto_rnd_prio > priority) | ||
208 | { | ||
209 | memcpy (&_gnutls_rnd_ops, s, sizeof (*s)); | ||
210 | crypto_rnd_prio = priority; | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | return GNUTLS_E_CRYPTO_ALREADY_REGISTERED-209; | ||
215 | } | ||
216 | |||
217 | /*- | ||
218 | * gnutls_crypto_single_mac_register: | ||
219 | * @algorithm: is the gnutls algorithm identifier | ||
220 | * @priority: is the priority of the algorithm | ||
221 | * @s: is a structure holding new algorithms's data | ||
222 | * | ||
223 | * This function will register a MAC algorithm to be used by gnutls. | ||
224 | * Any algorithm registered will override the included algorithms and | ||
225 | * by convention kernel implemented algorithms have priority of 90 | ||
226 | * and CPU-assisted of 80. | ||
227 | * The algorithm with the lowest priority will be used by gnutls. | ||
228 | * | ||
229 | * This function should be called before gnutls_global_init(). | ||
230 | * | ||
231 | * For simplicity you can use the convenience | ||
232 | * gnutls_crypto_single_mac_register() macro. | ||
233 | * | ||
234 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. | ||
235 | * | ||
236 | * Since: 2.6.0 | ||
237 | -*/ | ||
238 | int | ||
239 | gnutls_crypto_single_mac_register (gnutls_mac_algorithm_t algorithm, | ||
240 | int priority, | ||
241 | const gnutls_crypto_mac_st * s) | ||
242 | { | ||
243 | return _algo_register (&glob_ml, algorithm, priority, s); | ||
244 | } | ||
245 | |||
246 | const gnutls_crypto_mac_st * | ||
247 | _gnutls_get_crypto_mac (gnutls_mac_algorithm_t algo) | ||
248 | { | ||
249 | return _get_algo (&glob_ml, algo); | ||
250 | } | ||
251 | |||
252 | /*- | ||
253 | * gnutls_crypto_single_digest_register: | ||
254 | * @algorithm: is the gnutls algorithm identifier | ||
255 | * @priority: is the priority of the algorithm | ||
256 | * @s: is a structure holding new algorithms's data | ||
257 | * | ||
258 | * This function will register a digest (hash) algorithm to be used by | ||
259 | * gnutls. Any algorithm registered will override the included | ||
260 | * algorithms and by convention kernel implemented algorithms have | ||
261 | * priority of 90 and CPU-assisted of 80. The algorithm with the lowest priority will be | ||
262 | * used by gnutls. | ||
263 | * | ||
264 | * This function should be called before gnutls_global_init(). | ||
265 | * | ||
266 | * For simplicity you can use the convenience | ||
267 | * gnutls_crypto_single_digest_register() macro. | ||
268 | * | ||
269 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. | ||
270 | * | ||
271 | * Since: 2.6.0 | ||
272 | -*/ | ||
273 | int | ||
274 | gnutls_crypto_single_digest_register (gnutls_digest_algorithm_t algorithm, | ||
275 | int priority, | ||
276 | const gnutls_crypto_digest_st * s) | ||
277 | { | ||
278 | return _algo_register (&glob_dl, algorithm, priority, s); | ||
279 | } | ||
280 | |||
281 | const gnutls_crypto_digest_st * | ||
282 | _gnutls_get_crypto_digest (gnutls_digest_algorithm_t algo) | ||
283 | { | ||
284 | return _get_algo (&glob_dl, algo); | ||
285 | } | ||
286 | |||
287 | /*- | ||
288 | * gnutls_crypto_bigint_register: | ||
289 | * @priority: is the priority of the interface | ||
290 | * @s: is a structure holding new interface's data | ||
291 | * | ||
292 | * This function will register an interface for gnutls to operate | ||
293 | * on big integers. Any interface registered will override | ||
294 | * the included interface. The interface with the lowest | ||
295 | * priority will be used by gnutls. | ||
296 | * | ||
297 | * Note that the bigint interface must interoperate with the public | ||
298 | * key interface. Thus if this interface is updated the | ||
299 | * gnutls_crypto_pk_register() should also be used. | ||
300 | * | ||
301 | * This function should be called before gnutls_global_init(). | ||
302 | * | ||
303 | * For simplicity you can use the convenience gnutls_crypto_bigint_register() | ||
304 | * macro. | ||
305 | * | ||
306 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. | ||
307 | * | ||
308 | * Since: 2.6.0 | ||
309 | -*/ | ||
310 | int | ||
311 | gnutls_crypto_bigint_register (int priority, | ||
312 | const gnutls_crypto_bigint_st * s) | ||
313 | { | ||
314 | if (crypto_bigint_prio > priority) | ||
315 | { | ||
316 | memcpy (&_gnutls_mpi_ops, s, sizeof (*s)); | ||
317 | crypto_bigint_prio = priority; | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | return GNUTLS_E_CRYPTO_ALREADY_REGISTERED-209; | ||
322 | } | ||
323 | |||
324 | /*- | ||
325 | * gnutls_crypto_pk_register: | ||
326 | * @priority: is the priority of the interface | ||
327 | * @s: is a structure holding new interface's data | ||
328 | * | ||
329 | * This function will register an interface for gnutls to operate | ||
330 | * on public key operations. Any interface registered will override | ||
331 | * the included interface. The interface with the lowest | ||
332 | * priority will be used by gnutls. | ||
333 | * | ||
334 | * Note that the bigint interface must interoperate with the bigint | ||
335 | * interface. Thus if this interface is updated the | ||
336 | * gnutls_crypto_bigint_register() should also be used. | ||
337 | * | ||
338 | * This function should be called before gnutls_global_init(). | ||
339 | * | ||
340 | * For simplicity you can use the convenience gnutls_crypto_pk_register() | ||
341 | * macro. | ||
342 | * | ||
343 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. | ||
344 | * | ||
345 | * Since: 2.6.0 | ||
346 | -*/ | ||
347 | int | ||
348 | gnutls_crypto_pk_register (int priority, | ||
349 | const gnutls_crypto_pk_st * s) | ||
350 | { | ||
351 | if (crypto_pk_prio > priority) | ||
352 | { | ||
353 | memcpy (&_gnutls_pk_ops, s, sizeof (*s)); | ||
354 | crypto_pk_prio = priority; | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | return GNUTLS_E_CRYPTO_ALREADY_REGISTERED-209; | ||
359 | } | ||
360 | |||
361 | /*- | ||
362 | * gnutls_crypto_cipher_register: | ||
363 | * @priority: is the priority of the cipher interface | ||
364 | * @s: is a structure holding new interface's data | ||
365 | * | ||
366 | * This function will register a cipher interface to be used by | ||
367 | * gnutls. Any interface registered will override the included engine | ||
368 | * and by convention kernel implemented interfaces should have | ||
369 | * priority of 90 and CPU-assisted of 80. The interface with the lowest priority will be used | ||
370 | * by gnutls. | ||
371 | * | ||
372 | * This function should be called before gnutls_global_init(). | ||
373 | * | ||
374 | * For simplicity you can use the convenience | ||
375 | * gnutls_crypto_cipher_register() macro. | ||
376 | * | ||
377 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. | ||
378 | * | ||
379 | * Since: 2.6.0 | ||
380 | -*/ | ||
381 | int | ||
382 | gnutls_crypto_cipher_register (int priority, | ||
383 | const gnutls_crypto_cipher_st * s) | ||
384 | { | ||
385 | if (crypto_cipher_prio > priority) | ||
386 | { | ||
387 | memcpy (&_gnutls_cipher_ops, s, sizeof (*s)); | ||
388 | crypto_cipher_prio = priority; | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | return GNUTLS_E_CRYPTO_ALREADY_REGISTERED-209; | ||
393 | } | ||
394 | |||
395 | /*- | ||
396 | * gnutls_crypto_mac_register: | ||
397 | * @priority: is the priority of the mac interface | ||
398 | * @s: is a structure holding new interface's data | ||
399 | * | ||
400 | * This function will register a mac interface to be used by | ||
401 | * gnutls. Any interface registered will override the included engine | ||
402 | * and by convention kernel implemented interfaces should have | ||
403 | * priority of 90 and CPU-assisted of 80. The interface with the lowest priority will be used | ||
404 | * by gnutls. | ||
405 | * | ||
406 | * This function should be called before gnutls_global_init(). | ||
407 | * | ||
408 | * For simplicity you can use the convenience | ||
409 | * gnutls_crypto_digest_register() macro. | ||
410 | * | ||
411 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. | ||
412 | * | ||
413 | * Since: 2.6.0 | ||
414 | -*/ | ||
415 | int | ||
416 | gnutls_crypto_mac_register (int priority, | ||
417 | const gnutls_crypto_mac_st * s) | ||
418 | { | ||
419 | if (crypto_mac_prio > priority) | ||
420 | { | ||
421 | memcpy (&_gnutls_mac_ops, s, sizeof (*s)); | ||
422 | crypto_mac_prio = priority; | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | return GNUTLS_E_CRYPTO_ALREADY_REGISTERED-209; | ||
427 | } | ||
428 | |||
429 | /*- | ||
430 | * gnutls_crypto_digest_register: | ||
431 | * @priority: is the priority of the digest interface | ||
432 | * @s: is a structure holding new interface's data | ||
433 | * | ||
434 | * This function will register a digest interface to be used by | ||
435 | * gnutls. Any interface registered will override the included engine | ||
436 | * and by convention kernel implemented interfaces should have | ||
437 | * priority of 90 and CPU-assisted of 80. The interface with the lowest priority will be used | ||
438 | * by gnutls. | ||
439 | * | ||
440 | * This function should be called before gnutls_global_init(). | ||
441 | * | ||
442 | * For simplicity you can use the convenience | ||
443 | * gnutls_crypto_digest_register() macro. | ||
444 | * | ||
445 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. | ||
446 | * | ||
447 | * Since: 2.6.0 | ||
448 | -*/ | ||
449 | int | ||
450 | gnutls_crypto_digest_register (int priority, | ||
451 | const gnutls_crypto_digest_st * s) | ||
452 | { | ||
453 | if (crypto_digest_prio > priority) | ||
454 | { | ||
455 | memcpy (&_gnutls_digest_ops, s, sizeof (*s)); | ||
456 | crypto_digest_prio = priority; | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | return GNUTLS_E_CRYPTO_ALREADY_REGISTERED-209; | ||
461 | } |