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>
28 #include <gnutls_mpi.h>
29 #include <gnutls_pk.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
43 struct algo_list
*next
;
46 #define cipher_list algo_list
47 #define mac_list algo_list
48 #define digest_list algo_list
51 _algo_register (algo_list
* al
, int algorithm
, int priority
, const void *s
)
54 algo_list
*last_cl
= al
;
56 /* look if there is any cipher with lowest priority. In that case do not add.
59 while (cl
&& cl
->alg_data
)
61 if (cl
->algorithm
== algorithm
)
63 if (cl
->priority
< priority
)
66 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;
70 /* the current has higher priority -> overwrite */
71 cl
->algorithm
= algorithm
;
72 cl
->priority
= priority
;
82 cl
= gnutls_calloc (1, sizeof (cipher_list
));
87 return GNUTLS_E_MEMORY_ERROR
;
90 last_cl
->algorithm
= algorithm
;
91 last_cl
->priority
= priority
;
92 last_cl
->alg_data
= s
;
100 _get_algo (algo_list
* al
, int algo
)
104 /* look if there is any cipher with lowest priority. In that case do not add.
107 while (cl
&& cl
->alg_data
)
109 if (cl
->algorithm
== algo
)
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
};
124 _deregister (algo_list
* cl
)
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
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.
170 gnutls_crypto_single_cipher_register (gnutls_cipher_algorithm_t algorithm
,
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
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.
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
;
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.
239 gnutls_crypto_single_mac_register (gnutls_mac_algorithm_t algorithm
,
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
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.
274 gnutls_crypto_single_digest_register (gnutls_digest_algorithm_t algorithm
,
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()
306 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
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
;
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()
343 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
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
;
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
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.
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
;
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
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.
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
;
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
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.
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
;
460 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;