Remove.
[gnutls.git] / lib / crypto.c
blob48ef27eb6c7aa1dfd76c02b7770ff965c9cd4163
1 /*
2 * Copyright (C) 2008, 2010 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library 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,
21 * USA
25 #include <gnutls_errors.h>
26 #include <gnutls_int.h>
27 #include <gnutls/crypto.h>
28 #include <crypto.h>
29 #include <gnutls_mpi.h>
30 #include <gnutls_pk.h>
31 #include <random.h>
32 #include <gnutls_cipher_int.h>
34 typedef struct algo_list
36 int algorithm;
37 int priority;
38 const void *alg_data;
39 struct algo_list *next;
40 } algo_list;
42 #define cipher_list algo_list
43 #define mac_list algo_list
44 #define digest_list algo_list
46 static int
47 _algo_register (algo_list * al, int algorithm, int priority, const void *s)
49 algo_list *cl;
50 algo_list *last_cl = al;
52 /* look if there is any cipher with lowest priority. In that case do not add.
54 cl = al;
55 while (cl && cl->alg_data)
57 if (cl->algorithm == algorithm)
59 if (cl->priority < priority)
61 gnutls_assert ();
62 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
64 else
66 /* the current has higher priority -> overwrite */
67 cl->algorithm = algorithm;
68 cl->priority = priority;
69 cl->alg_data = s;
70 return 0;
73 cl = cl->next;
74 if (cl)
75 last_cl = cl;
78 cl = gnutls_calloc (1, sizeof (cipher_list));
80 if (cl == NULL)
82 gnutls_assert ();
83 return GNUTLS_E_MEMORY_ERROR;
86 last_cl->algorithm = algorithm;
87 last_cl->priority = priority;
88 last_cl->alg_data = s;
89 last_cl->next = cl;
91 return 0;
95 static const void *
96 _get_algo (algo_list * al, int algo)
98 cipher_list *cl;
100 /* look if there is any cipher with lowest priority. In that case do not add.
102 cl = al;
103 while (cl && cl->alg_data)
105 if (cl->algorithm == algo)
107 return cl->alg_data;
109 cl = cl->next;
112 return NULL;
115 static cipher_list glob_cl = { GNUTLS_CIPHER_NULL, 0, NULL, NULL };
116 static mac_list glob_ml = { GNUTLS_MAC_NULL, 0, NULL, NULL };
117 static digest_list glob_dl = { GNUTLS_MAC_NULL, 0, NULL, NULL };
119 static void
120 _deregister (algo_list * cl)
122 algo_list *next;
124 next = cl->next;
125 cl->next = NULL;
126 cl = next;
128 while (cl)
130 next = cl->next;
131 gnutls_free (cl);
132 cl = next;
136 void
137 _gnutls_crypto_deregister (void)
139 _deregister (&glob_cl);
140 _deregister (&glob_ml);
141 _deregister (&glob_dl);
145 * gnutls_crypto_single_cipher_register2:
146 * @algorithm: is the gnutls algorithm identifier
147 * @priority: is the priority of the algorithm
148 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
149 * @s: is a structure holding new cipher's data
151 * This function will register a cipher algorithm to be used by
152 * gnutls. Any algorithm registered will override the included
153 * algorithms and by convention kernel implemented algorithms have
154 * priority of 90. The algorithm with the lowest priority will be
155 * used by gnutls.
157 * This function should be called before gnutls_global_init().
159 * For simplicity you can use the convenience
160 * gnutls_crypto_single_cipher_register() macro.
162 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
164 * Since: 2.6.0
167 gnutls_crypto_single_cipher_register2 (gnutls_cipher_algorithm_t algorithm,
168 int priority, int version,
169 const gnutls_crypto_cipher_st * s)
171 if (version != GNUTLS_CRYPTO_API_VERSION)
173 gnutls_assert ();
174 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
177 return _algo_register (&glob_cl, algorithm, priority, s);
180 const gnutls_crypto_cipher_st *
181 _gnutls_get_crypto_cipher (gnutls_cipher_algorithm_t algo)
183 return _get_algo (&glob_cl, algo);
187 * gnutls_crypto_rnd_register2:
188 * @priority: is the priority of the generator
189 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
190 * @s: is a structure holding new generator's data
192 * This function will register a random generator to be used by
193 * gnutls. Any generator registered will override the included
194 * generator and by convention kernel implemented generators have
195 * priority of 90. The generator with the lowest priority will be
196 * used by gnutls.
198 * This function should be called before gnutls_global_init().
200 * For simplicity you can use the convenience
201 * gnutls_crypto_rnd_register() macro.
203 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
205 * Since: 2.6.0
208 gnutls_crypto_rnd_register2 (int priority, int version,
209 const gnutls_crypto_rnd_st * s)
211 if (version != GNUTLS_CRYPTO_API_VERSION)
213 gnutls_assert ();
214 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
217 if (crypto_rnd_prio > priority)
219 memcpy (&_gnutls_rnd_ops, s, sizeof (*s));
220 crypto_rnd_prio = priority;
221 return 0;
224 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
228 * gnutls_crypto_single_mac_register2:
229 * @algorithm: is the gnutls algorithm identifier
230 * @priority: is the priority of the algorithm
231 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
232 * @s: is a structure holding new algorithms's data
234 * This function will register a MAC algorithm to be used by gnutls.
235 * Any algorithm registered will override the included algorithms and
236 * by convention kernel implemented algorithms have priority of 90.
237 * The algorithm with the lowest priority will be used by gnutls.
239 * This function should be called before gnutls_global_init().
241 * For simplicity you can use the convenience
242 * gnutls_crypto_single_mac_register() macro.
244 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
246 * Since: 2.6.0
249 gnutls_crypto_single_mac_register2 (gnutls_mac_algorithm_t algorithm,
250 int priority, int version,
251 const gnutls_crypto_mac_st * s)
253 if (version != GNUTLS_CRYPTO_API_VERSION)
255 gnutls_assert ();
256 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
259 return _algo_register (&glob_ml, algorithm, priority, s);
262 const gnutls_crypto_mac_st *
263 _gnutls_get_crypto_mac (gnutls_mac_algorithm_t algo)
265 return _get_algo (&glob_ml, algo);
269 * gnutls_crypto_single_digest_register2:
270 * @algorithm: is the gnutls algorithm identifier
271 * @priority: is the priority of the algorithm
272 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
273 * @s: is a structure holding new algorithms's data
275 * This function will register a digest (hash) algorithm to be used by
276 * gnutls. Any algorithm registered will override the included
277 * algorithms and by convention kernel implemented algorithms have
278 * priority of 90. The algorithm with the lowest priority will be
279 * used by gnutls.
281 * This function should be called before gnutls_global_init().
283 * For simplicity you can use the convenience
284 * gnutls_crypto_single_digest_register() macro.
286 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
288 * Since: 2.6.0
291 gnutls_crypto_single_digest_register2 (gnutls_digest_algorithm_t algorithm,
292 int priority, int version,
293 const gnutls_crypto_digest_st * s)
295 if (version != GNUTLS_CRYPTO_API_VERSION)
297 gnutls_assert ();
298 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
301 return _algo_register (&glob_dl, algorithm, priority, s);
304 const gnutls_crypto_digest_st *
305 _gnutls_get_crypto_digest (gnutls_digest_algorithm_t algo)
307 return _get_algo (&glob_dl, algo);
311 * gnutls_crypto_bigint_register2:
312 * @priority: is the priority of the interface
313 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
314 * @s: is a structure holding new interface's data
316 * This function will register an interface for gnutls to operate
317 * on big integers. Any interface registered will override
318 * the included interface. The interface with the lowest
319 * priority will be used by gnutls.
321 * Note that the bigint interface must interoperate with the public
322 * key interface. Thus if this interface is updated the
323 * gnutls_crypto_pk_register() should also be used.
325 * This function should be called before gnutls_global_init().
327 * For simplicity you can use the convenience gnutls_crypto_bigint_register()
328 * macro.
330 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
332 * Since: 2.6.0
335 gnutls_crypto_bigint_register2 (int priority, int version,
336 const gnutls_crypto_bigint_st * s)
338 if (version != GNUTLS_CRYPTO_API_VERSION)
340 gnutls_assert ();
341 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
344 if (crypto_bigint_prio > priority)
346 memcpy (&_gnutls_mpi_ops, s, sizeof (*s));
347 crypto_bigint_prio = priority;
348 return 0;
351 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
355 * gnutls_crypto_pk_register2:
356 * @priority: is the priority of the interface
357 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
358 * @s: is a structure holding new interface's data
360 * This function will register an interface for gnutls to operate
361 * on public key operations. Any interface registered will override
362 * the included interface. The interface with the lowest
363 * priority will be used by gnutls.
365 * Note that the bigint interface must interoperate with the bigint
366 * interface. Thus if this interface is updated the
367 * gnutls_crypto_bigint_register() should also be used.
369 * This function should be called before gnutls_global_init().
371 * For simplicity you can use the convenience gnutls_crypto_pk_register()
372 * macro.
374 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
376 * Since: 2.6.0
379 gnutls_crypto_pk_register2 (int priority, int version,
380 const gnutls_crypto_pk_st * s)
382 if (version != GNUTLS_CRYPTO_API_VERSION)
384 gnutls_assert ();
385 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
388 if (crypto_pk_prio > priority)
390 memcpy (&_gnutls_pk_ops, s, sizeof (*s));
391 crypto_pk_prio = priority;
392 return 0;
395 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
399 * gnutls_crypto_cipher_register2:
400 * @priority: is the priority of the cipher interface
401 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
402 * @s: is a structure holding new interface's data
404 * This function will register a cipher interface to be used by
405 * gnutls. Any interface registered will override the included engine
406 * and by convention kernel implemented interfaces should have
407 * priority of 90. The interface with the lowest priority will be used
408 * by gnutls.
410 * This function should be called before gnutls_global_init().
412 * For simplicity you can use the convenience
413 * gnutls_crypto_cipher_register() macro.
415 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
417 * Since: 2.6.0
420 gnutls_crypto_cipher_register2 (int priority, int version,
421 const gnutls_crypto_cipher_st * s)
423 if (version != GNUTLS_CRYPTO_API_VERSION)
425 gnutls_assert ();
426 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
429 if (crypto_cipher_prio > priority)
431 memcpy (&_gnutls_cipher_ops, s, sizeof (*s));
432 crypto_cipher_prio = priority;
433 return 0;
436 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
440 * gnutls_crypto_mac_register2:
441 * @priority: is the priority of the mac interface
442 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
443 * @s: is a structure holding new interface's data
445 * This function will register a mac interface to be used by
446 * gnutls. Any interface registered will override the included engine
447 * and by convention kernel implemented interfaces should have
448 * priority of 90. The interface with the lowest priority will be used
449 * by gnutls.
451 * This function should be called before gnutls_global_init().
453 * For simplicity you can use the convenience
454 * gnutls_crypto_digest_register() macro.
456 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
458 * Since: 2.6.0
461 gnutls_crypto_mac_register2 (int priority, int version,
462 const gnutls_crypto_mac_st * s)
464 if (version != GNUTLS_CRYPTO_API_VERSION)
466 gnutls_assert ();
467 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
470 if (crypto_mac_prio > priority)
472 memcpy (&_gnutls_mac_ops, s, sizeof (*s));
473 crypto_mac_prio = priority;
474 return 0;
477 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
481 * gnutls_crypto_digest_register2:
482 * @priority: is the priority of the digest interface
483 * @version: should be set to %GNUTLS_CRYPTO_API_VERSION
484 * @s: is a structure holding new interface's data
486 * This function will register a digest interface to be used by
487 * gnutls. Any interface registered will override the included engine
488 * and by convention kernel implemented interfaces should have
489 * priority of 90. The interface with the lowest priority will be used
490 * by gnutls.
492 * This function should be called before gnutls_global_init().
494 * For simplicity you can use the convenience
495 * gnutls_crypto_digest_register() macro.
497 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
499 * Since: 2.6.0
502 gnutls_crypto_digest_register2 (int priority, int version,
503 const gnutls_crypto_digest_st * s)
505 if (version != GNUTLS_CRYPTO_API_VERSION)
507 gnutls_assert ();
508 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
511 if (crypto_digest_prio > priority)
513 memcpy (&_gnutls_digest_ops, s, sizeof (*s));
514 crypto_digest_prio = priority;
515 return 0;
518 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;