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,
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 typedef struct algo_list
39 struct algo_list
*next
;
42 #define cipher_list algo_list
43 #define mac_list algo_list
44 #define digest_list algo_list
47 _algo_register (algo_list
* al
, int algorithm
, int priority
, const void *s
)
50 algo_list
*last_cl
= al
;
52 /* look if there is any cipher with lowest priority. In that case do not add.
55 while (cl
&& cl
->alg_data
)
57 if (cl
->algorithm
== algorithm
)
59 if (cl
->priority
< priority
)
62 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;
66 /* the current has higher priority -> overwrite */
67 cl
->algorithm
= algorithm
;
68 cl
->priority
= priority
;
78 cl
= gnutls_calloc (1, sizeof (cipher_list
));
83 return GNUTLS_E_MEMORY_ERROR
;
86 last_cl
->algorithm
= algorithm
;
87 last_cl
->priority
= priority
;
88 last_cl
->alg_data
= s
;
96 _get_algo (algo_list
* al
, int algo
)
100 /* look if there is any cipher with lowest priority. In that case do not add.
103 while (cl
&& cl
->alg_data
)
105 if (cl
->algorithm
== algo
)
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
};
120 _deregister (algo_list
* cl
)
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
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.
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
)
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
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.
208 gnutls_crypto_rnd_register2 (int priority
, int version
,
209 const gnutls_crypto_rnd_st
* s
)
211 if (version
!= GNUTLS_CRYPTO_API_VERSION
)
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
;
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.
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
)
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
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.
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
)
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()
330 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
335 gnutls_crypto_bigint_register2 (int priority
, int version
,
336 const gnutls_crypto_bigint_st
* s
)
338 if (version
!= GNUTLS_CRYPTO_API_VERSION
)
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
;
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()
374 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
379 gnutls_crypto_pk_register2 (int priority
, int version
,
380 const gnutls_crypto_pk_st
* s
)
382 if (version
!= GNUTLS_CRYPTO_API_VERSION
)
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
;
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
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.
420 gnutls_crypto_cipher_register2 (int priority
, int version
,
421 const gnutls_crypto_cipher_st
* s
)
423 if (version
!= GNUTLS_CRYPTO_API_VERSION
)
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
;
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
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.
461 gnutls_crypto_mac_register2 (int priority
, int version
,
462 const gnutls_crypto_mac_st
* s
)
464 if (version
!= GNUTLS_CRYPTO_API_VERSION
)
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
;
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
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.
502 gnutls_crypto_digest_register2 (int priority
, int version
,
503 const gnutls_crypto_digest_st
* s
)
505 if (version
!= GNUTLS_CRYPTO_API_VERSION
)
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
;
518 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;