2 * Copyright (C) 2008, 2010 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 2.1 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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 #include <gnutls_errors.h>
26 #include <gnutls_int.h>
27 #include <gnutls/crypto.h>
29 #include <gnutls_mpi.h>
30 #include <gnutls_pk.h>
32 #include <gnutls_cipher_int.h>
34 /* default values for priorities */
35 int crypto_mac_prio = INT_MAX;
36 int crypto_digest_prio = INT_MAX;
37 int crypto_cipher_prio = INT_MAX;
39 typedef struct algo_list
44 struct algo_list *next;
47 #define cipher_list algo_list
48 #define mac_list algo_list
49 #define digest_list algo_list
52 _algo_register (algo_list * al, int algorithm, int priority, const void *s)
55 algo_list *last_cl = al;
57 /* look if there is any cipher with lowest priority. In that case do not add.
60 while (cl && cl->alg_data)
62 if (cl->algorithm == algorithm)
64 if (cl->priority < priority)
67 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
71 /* the current has higher priority -> overwrite */
72 cl->algorithm = algorithm;
73 cl->priority = priority;
83 cl = gnutls_calloc (1, sizeof (cipher_list));
88 return GNUTLS_E_MEMORY_ERROR;
91 last_cl->algorithm = algorithm;
92 last_cl->priority = priority;
93 last_cl->alg_data = s;
101 _get_algo (algo_list * al, int algo)
105 /* look if there is any cipher with lowest priority. In that case do not add.
108 while (cl && cl->alg_data)
110 if (cl->algorithm == algo)
120 static cipher_list glob_cl = { GNUTLS_CIPHER_NULL, 0, NULL, NULL };
121 static mac_list glob_ml = { GNUTLS_MAC_NULL, 0, NULL, NULL };
122 static digest_list glob_dl = { GNUTLS_MAC_NULL, 0, NULL, NULL };
125 _deregister (algo_list * cl)
142 _gnutls_crypto_deregister (void)
144 _deregister (&glob_cl);
145 _deregister (&glob_ml);
146 _deregister (&glob_dl);
150 * gnutls_crypto_single_cipher_register2:
151 * @algorithm: is the gnutls algorithm identifier
152 * @priority: is the priority of the algorithm
153 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
154 * @s: is a structure holding new cipher's data
156 * This function will register a cipher algorithm to be used by
157 * gnutls. Any algorithm registered will override the included
158 * algorithms and by convention kernel implemented algorithms have
159 * priority of 90. The algorithm with the lowest priority will be
162 * This function should be called before gnutls_global_init().
164 * For simplicity you can use the convenience
165 * gnutls_crypto_single_cipher_register() macro.
167 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
172 gnutls_crypto_single_cipher_register2 (gnutls_cipher_algorithm_t algorithm,
173 int priority, int version,
174 const gnutls_crypto_cipher_st * s)
176 if (version != GNUTLS_CRYPTO_API_VERSION)
179 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
182 return _algo_register (&glob_cl, algorithm, priority, s);
185 const gnutls_crypto_cipher_st *
186 _gnutls_get_crypto_cipher (gnutls_cipher_algorithm_t algo)
188 return _get_algo (&glob_cl, algo);
192 * gnutls_crypto_rnd_register2:
193 * @priority: is the priority of the generator
194 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
195 * @s: is a structure holding new generator's data
197 * This function will register a random generator to be used by
198 * gnutls. Any generator registered will override the included
199 * generator and by convention kernel implemented generators have
200 * priority of 90. The generator with the lowest priority will be
203 * This function should be called before gnutls_global_init().
205 * For simplicity you can use the convenience
206 * gnutls_crypto_rnd_register() macro.
208 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
213 gnutls_crypto_rnd_register2 (int priority, int version,
214 const gnutls_crypto_rnd_st * s)
216 if (version != GNUTLS_CRYPTO_API_VERSION)
219 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
222 if (crypto_rnd_prio > priority)
224 memcpy (&_gnutls_rnd_ops, s, sizeof (*s));
225 crypto_rnd_prio = priority;
229 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
233 * gnutls_crypto_single_mac_register2:
234 * @algorithm: is the gnutls algorithm identifier
235 * @priority: is the priority of the algorithm
236 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
237 * @s: is a structure holding new algorithms's data
239 * This function will register a MAC algorithm to be used by gnutls.
240 * Any algorithm registered will override the included algorithms and
241 * by convention kernel implemented algorithms have priority of 90.
242 * The algorithm with the lowest priority will be used by gnutls.
244 * This function should be called before gnutls_global_init().
246 * For simplicity you can use the convenience
247 * gnutls_crypto_single_mac_register() macro.
249 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
254 gnutls_crypto_single_mac_register2 (gnutls_mac_algorithm_t algorithm,
255 int priority, int version,
256 const gnutls_crypto_mac_st * s)
258 if (version != GNUTLS_CRYPTO_API_VERSION)
261 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
264 return _algo_register (&glob_ml, algorithm, priority, s);
267 const gnutls_crypto_mac_st *
268 _gnutls_get_crypto_mac (gnutls_mac_algorithm_t algo)
270 return _get_algo (&glob_ml, algo);
274 * gnutls_crypto_single_digest_register2:
275 * @algorithm: is the gnutls algorithm identifier
276 * @priority: is the priority of the algorithm
277 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
278 * @s: is a structure holding new algorithms's data
280 * This function will register a digest (hash) algorithm to be used by
281 * gnutls. Any algorithm registered will override the included
282 * algorithms and by convention kernel implemented algorithms have
283 * priority of 90. The algorithm with the lowest priority will be
286 * This function should be called before gnutls_global_init().
288 * For simplicity you can use the convenience
289 * gnutls_crypto_single_digest_register() macro.
291 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
296 gnutls_crypto_single_digest_register2 (gnutls_digest_algorithm_t algorithm,
297 int priority, int version,
298 const gnutls_crypto_digest_st * s)
300 if (version != GNUTLS_CRYPTO_API_VERSION)
303 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
306 return _algo_register (&glob_dl, algorithm, priority, s);
309 const gnutls_crypto_digest_st *
310 _gnutls_get_crypto_digest (gnutls_digest_algorithm_t algo)
312 return _get_algo (&glob_dl, algo);
316 * gnutls_crypto_bigint_register2:
317 * @priority: is the priority of the interface
318 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
319 * @s: is a structure holding new interface's data
321 * This function will register an interface for gnutls to operate
322 * on big integers. Any interface registered will override
323 * the included interface. The interface with the lowest
324 * priority will be used by gnutls.
326 * Note that the bigint interface must interoperate with the public
327 * key interface. Thus if this interface is updated the
328 * gnutls_crypto_pk_register() should also be used.
330 * This function should be called before gnutls_global_init().
332 * For simplicity you can use the convenience gnutls_crypto_bigint_register()
335 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
340 gnutls_crypto_bigint_register2 (int priority, int version,
341 const gnutls_crypto_bigint_st * s)
343 if (version != GNUTLS_CRYPTO_API_VERSION)
346 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
349 if (crypto_bigint_prio > priority)
351 memcpy (&_gnutls_mpi_ops, s, sizeof (*s));
352 crypto_bigint_prio = priority;
356 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
360 * gnutls_crypto_pk_register2:
361 * @priority: is the priority of the interface
362 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
363 * @s: is a structure holding new interface's data
365 * This function will register an interface for gnutls to operate
366 * on public key operations. Any interface registered will override
367 * the included interface. The interface with the lowest
368 * priority will be used by gnutls.
370 * Note that the bigint interface must interoperate with the bigint
371 * interface. Thus if this interface is updated the
372 * gnutls_crypto_bigint_register() should also be used.
374 * This function should be called before gnutls_global_init().
376 * For simplicity you can use the convenience gnutls_crypto_pk_register()
379 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
384 gnutls_crypto_pk_register2 (int priority, int version,
385 const gnutls_crypto_pk_st * s)
387 if (version != GNUTLS_CRYPTO_API_VERSION)
390 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
393 if (crypto_pk_prio > priority)
395 memcpy (&_gnutls_pk_ops, s, sizeof (*s));
396 crypto_pk_prio = priority;
400 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
404 * gnutls_crypto_cipher_register2:
405 * @priority: is the priority of the cipher interface
406 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
407 * @s: is a structure holding new interface's data
409 * This function will register a cipher interface to be used by
410 * gnutls. Any interface registered will override the included engine
411 * and by convention kernel implemented interfaces should have
412 * priority of 90. The interface with the lowest priority will be used
415 * This function should be called before gnutls_global_init().
417 * For simplicity you can use the convenience
418 * gnutls_crypto_cipher_register() macro.
420 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
425 gnutls_crypto_cipher_register2 (int priority, int version,
426 const gnutls_crypto_cipher_st * s)
428 if (version != GNUTLS_CRYPTO_API_VERSION)
431 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
434 if (crypto_cipher_prio > priority)
436 memcpy (&_gnutls_cipher_ops, s, sizeof (*s));
437 crypto_cipher_prio = priority;
441 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
445 * gnutls_crypto_mac_register2:
446 * @priority: is the priority of the mac interface
447 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
448 * @s: is a structure holding new interface's data
450 * This function will register a mac interface to be used by
451 * gnutls. Any interface registered will override the included engine
452 * and by convention kernel implemented interfaces should have
453 * priority of 90. The interface with the lowest priority will be used
456 * This function should be called before gnutls_global_init().
458 * For simplicity you can use the convenience
459 * gnutls_crypto_digest_register() macro.
461 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
466 gnutls_crypto_mac_register2 (int priority, int version,
467 const gnutls_crypto_mac_st * s)
469 if (version != GNUTLS_CRYPTO_API_VERSION)
472 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
475 if (crypto_mac_prio > priority)
477 memcpy (&_gnutls_mac_ops, s, sizeof (*s));
478 crypto_mac_prio = priority;
482 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
486 * gnutls_crypto_digest_register2:
487 * @priority: is the priority of the digest interface
488 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
489 * @s: is a structure holding new interface's data
491 * This function will register a digest interface to be used by
492 * gnutls. Any interface registered will override the included engine
493 * and by convention kernel implemented interfaces should have
494 * priority of 90. The interface with the lowest priority will be used
497 * This function should be called before gnutls_global_init().
499 * For simplicity you can use the convenience
500 * gnutls_crypto_digest_register() macro.
502 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
507 gnutls_crypto_digest_register2 (int priority, int version,
508 const gnutls_crypto_digest_st * s)
510 if (version != GNUTLS_CRYPTO_API_VERSION)
513 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
516 if (crypto_digest_prio > priority)
518 memcpy (&_gnutls_digest_ops, s, sizeof (*s));
519 crypto_digest_prio = priority;
523 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;