cleaned up errno handling.
[gnutls.git] / lib / crypto-backend.c
blob6d081555839527157b24214f79a6c70e3e26c103
1 /*
2 * Copyright (C) 2008-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
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.
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.
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/>
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>
33 /* default values for priorities */
34 int crypto_mac_prio = INT_MAX;
35 int crypto_digest_prio = INT_MAX;
36 int crypto_cipher_prio = INT_MAX;
38 typedef struct algo_list
40 int algorithm;
41 int priority;
42 const void *alg_data;
43 struct algo_list *next;
44 } algo_list;
46 #define cipher_list algo_list
47 #define mac_list algo_list
48 #define digest_list algo_list
50 static int
51 _algo_register (algo_list * al, int algorithm, int priority, const void *s)
53 algo_list *cl;
54 algo_list *last_cl = al;
56 /* look if there is any cipher with lowest priority. In that case do not add.
58 cl = al;
59 while (cl && cl->alg_data)
61 if (cl->algorithm == algorithm)
63 if (cl->priority < priority)
65 gnutls_assert ();
66 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
68 else
70 /* the current has higher priority -> overwrite */
71 cl->algorithm = algorithm;
72 cl->priority = priority;
73 cl->alg_data = s;
74 return 0;
77 cl = cl->next;
78 if (cl)
79 last_cl = cl;
82 cl = gnutls_calloc (1, sizeof (cipher_list));
84 if (cl == NULL)
86 gnutls_assert ();
87 return GNUTLS_E_MEMORY_ERROR;
90 last_cl->algorithm = algorithm;
91 last_cl->priority = priority;
92 last_cl->alg_data = s;
93 last_cl->next = cl;
95 return 0;
99 static const void *
100 _get_algo (algo_list * al, int algo)
102 cipher_list *cl;
104 /* look if there is any cipher with lowest priority. In that case do not add.
106 cl = al;
107 while (cl && cl->alg_data)
109 if (cl->algorithm == algo)
111 return cl->alg_data;
113 cl = cl->next;
116 return NULL;
119 static cipher_list glob_cl = { GNUTLS_CIPHER_NULL, 0, NULL, NULL };
120 static mac_list glob_ml = { GNUTLS_MAC_NULL, 0, NULL, NULL };
121 static digest_list glob_dl = { GNUTLS_MAC_NULL, 0, NULL, NULL };
123 static void
124 _deregister (algo_list * cl)
126 algo_list *next;
128 next = cl->next;
129 cl->next = NULL;
130 cl = next;
132 while (cl)
134 next = cl->next;
135 gnutls_free (cl);
136 cl = next;
140 void
141 _gnutls_crypto_deregister (void)
143 _deregister (&glob_cl);
144 _deregister (&glob_ml);
145 _deregister (&glob_dl);
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
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.
160 * This function should be called before gnutls_global_init().
162 * For simplicity you can use the convenience
163 * gnutls_crypto_single_cipher_register() macro.
165 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
167 * Since: 2.6.0
170 gnutls_crypto_single_cipher_register (gnutls_cipher_algorithm_t algorithm,
171 int priority,
172 const gnutls_crypto_cipher_st * s)
174 return _algo_register (&glob_cl, algorithm, priority, s);
177 const gnutls_crypto_cipher_st *
178 _gnutls_get_crypto_cipher (gnutls_cipher_algorithm_t algo)
180 return _get_algo (&glob_cl, algo);
184 * gnutls_crypto_rnd_register:
185 * @priority: is the priority of the generator
186 * @s: is a structure holding new generator's data
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.
194 * This function should be called before gnutls_global_init().
196 * For simplicity you can use the convenience
197 * gnutls_crypto_rnd_register() macro.
199 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
201 * Since: 2.6.0
204 gnutls_crypto_rnd_register (int priority,
205 const gnutls_crypto_rnd_st * s)
207 if (crypto_rnd_prio > priority)
209 memcpy (&_gnutls_rnd_ops, s, sizeof (*s));
210 crypto_rnd_prio = priority;
211 return 0;
214 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
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
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.
229 * This function should be called before gnutls_global_init().
231 * For simplicity you can use the convenience
232 * gnutls_crypto_single_mac_register() macro.
234 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
236 * Since: 2.6.0
239 gnutls_crypto_single_mac_register (gnutls_mac_algorithm_t algorithm,
240 int priority,
241 const gnutls_crypto_mac_st * s)
243 return _algo_register (&glob_ml, algorithm, priority, s);
246 const gnutls_crypto_mac_st *
247 _gnutls_get_crypto_mac (gnutls_mac_algorithm_t algo)
249 return _get_algo (&glob_ml, algo);
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
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.
264 * This function should be called before gnutls_global_init().
266 * For simplicity you can use the convenience
267 * gnutls_crypto_single_digest_register() macro.
269 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
271 * Since: 2.6.0
274 gnutls_crypto_single_digest_register (gnutls_digest_algorithm_t algorithm,
275 int priority,
276 const gnutls_crypto_digest_st * s)
278 return _algo_register (&glob_dl, algorithm, priority, s);
281 const gnutls_crypto_digest_st *
282 _gnutls_get_crypto_digest (gnutls_digest_algorithm_t algo)
284 return _get_algo (&glob_dl, algo);
288 * gnutls_crypto_bigint_register:
289 * @priority: is the priority of the interface
290 * @s: is a structure holding new interface's data
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.
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.
301 * This function should be called before gnutls_global_init().
303 * For simplicity you can use the convenience gnutls_crypto_bigint_register()
304 * macro.
306 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
308 * Since: 2.6.0
311 gnutls_crypto_bigint_register (int priority,
312 const gnutls_crypto_bigint_st * s)
314 if (crypto_bigint_prio > priority)
316 memcpy (&_gnutls_mpi_ops, s, sizeof (*s));
317 crypto_bigint_prio = priority;
318 return 0;
321 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
325 * gnutls_crypto_pk_register:
326 * @priority: is the priority of the interface
327 * @s: is a structure holding new interface's data
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.
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.
338 * This function should be called before gnutls_global_init().
340 * For simplicity you can use the convenience gnutls_crypto_pk_register()
341 * macro.
343 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
345 * Since: 2.6.0
348 gnutls_crypto_pk_register (int priority,
349 const gnutls_crypto_pk_st * s)
351 if (crypto_pk_prio > priority)
353 memcpy (&_gnutls_pk_ops, s, sizeof (*s));
354 crypto_pk_prio = priority;
355 return 0;
358 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
362 * gnutls_crypto_cipher_register:
363 * @priority: is the priority of the cipher interface
364 * @s: is a structure holding new interface's data
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.
372 * This function should be called before gnutls_global_init().
374 * For simplicity you can use the convenience
375 * gnutls_crypto_cipher_register() macro.
377 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
379 * Since: 2.6.0
382 gnutls_crypto_cipher_register (int priority,
383 const gnutls_crypto_cipher_st * s)
385 if (crypto_cipher_prio > priority)
387 memcpy (&_gnutls_cipher_ops, s, sizeof (*s));
388 crypto_cipher_prio = priority;
389 return 0;
392 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
396 * gnutls_crypto_mac_register:
397 * @priority: is the priority of the mac interface
398 * @s: is a structure holding new interface's data
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.
406 * This function should be called before gnutls_global_init().
408 * For simplicity you can use the convenience
409 * gnutls_crypto_digest_register() macro.
411 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
413 * Since: 2.6.0
416 gnutls_crypto_mac_register (int priority,
417 const gnutls_crypto_mac_st * s)
419 if (crypto_mac_prio > priority)
421 memcpy (&_gnutls_mac_ops, s, sizeof (*s));
422 crypto_mac_prio = priority;
423 return 0;
426 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
430 * gnutls_crypto_digest_register:
431 * @priority: is the priority of the digest interface
432 * @s: is a structure holding new interface's data
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.
440 * This function should be called before gnutls_global_init().
442 * For simplicity you can use the convenience
443 * gnutls_crypto_digest_register() macro.
445 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
447 * Since: 2.6.0
450 gnutls_crypto_digest_register (int priority,
451 const gnutls_crypto_digest_st * s)
453 if (crypto_digest_prio > priority)
455 memcpy (&_gnutls_digest_ops, s, sizeof (*s));
456 crypto_digest_prio = priority;
457 return 0;
460 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;