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
;
57 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST
);
59 /* look if there is any cipher with lowest priority. In that case do not add.
62 while (cl
&& cl
->alg_data
)
64 if (cl
->algorithm
== algorithm
)
66 if (cl
->priority
< priority
)
69 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;
73 /* the current has higher priority -> overwrite */
74 cl
->algorithm
= algorithm
;
75 cl
->priority
= priority
;
85 cl
= gnutls_calloc (1, sizeof (cipher_list
));
90 return GNUTLS_E_MEMORY_ERROR
;
93 last_cl
->algorithm
= algorithm
;
94 last_cl
->priority
= priority
;
95 last_cl
->alg_data
= s
;
103 _get_algo (algo_list
* al
, int algo
)
107 /* look if there is any cipher with lowest priority. In that case do not add.
110 while (cl
&& cl
->alg_data
)
112 if (cl
->algorithm
== algo
)
122 static cipher_list glob_cl
= { GNUTLS_CIPHER_NULL
, 0, NULL
, NULL
};
123 static mac_list glob_ml
= { GNUTLS_MAC_NULL
, 0, NULL
, NULL
};
124 static digest_list glob_dl
= { GNUTLS_MAC_NULL
, 0, NULL
, NULL
};
127 _deregister (algo_list
* cl
)
144 _gnutls_crypto_deregister (void)
146 _deregister (&glob_cl
);
147 _deregister (&glob_ml
);
148 _deregister (&glob_dl
);
152 * gnutls_crypto_single_cipher_register:
153 * @algorithm: is the gnutls algorithm identifier
154 * @priority: is the priority of the algorithm
155 * @s: is a structure holding new cipher's data
157 * This function will register a cipher algorithm to be used by
158 * gnutls. Any algorithm registered will override the included
159 * algorithms and by convention kernel implemented algorithms have
160 * priority of 90 and CPU-assisted of 80. The algorithm with the lowest priority will be
163 * This function should be called before gnutls_global_init().
165 * For simplicity you can use the convenience
166 * gnutls_crypto_single_cipher_register() macro.
168 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
173 gnutls_crypto_single_cipher_register (gnutls_cipher_algorithm_t algorithm
,
175 const gnutls_crypto_cipher_st
* s
)
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_register:
188 * @priority: is the priority of the generator
189 * @s: is a structure holding new generator's data
191 * This function will register a random generator to be used by
192 * gnutls. Any generator registered will override the included
193 * generator and by convention kernel implemented generators have
194 * priority of 90 and CPU-assisted of 80. The generator with the lowest priority will be
197 * This function should be called before gnutls_global_init().
199 * For simplicity you can use the convenience
200 * gnutls_crypto_rnd_register() macro.
202 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
207 gnutls_crypto_rnd_register (int priority
,
208 const gnutls_crypto_rnd_st
* s
)
210 if (crypto_rnd_prio
> priority
)
212 memcpy (&_gnutls_rnd_ops
, s
, sizeof (*s
));
213 crypto_rnd_prio
= priority
;
217 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;
221 * gnutls_crypto_single_mac_register:
222 * @algorithm: is the gnutls algorithm identifier
223 * @priority: is the priority of the algorithm
224 * @s: is a structure holding new algorithms's data
226 * This function will register a MAC algorithm to be used by gnutls.
227 * Any algorithm registered will override the included algorithms and
228 * by convention kernel implemented algorithms have priority of 90
229 * and CPU-assisted of 80.
230 * The algorithm with the lowest priority will be used by gnutls.
232 * This function should be called before gnutls_global_init().
234 * For simplicity you can use the convenience
235 * gnutls_crypto_single_mac_register() macro.
237 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
242 gnutls_crypto_single_mac_register (gnutls_mac_algorithm_t algorithm
,
244 const gnutls_crypto_mac_st
* s
)
246 return _algo_register (&glob_ml
, algorithm
, priority
, s
);
249 const gnutls_crypto_mac_st
*
250 _gnutls_get_crypto_mac (gnutls_mac_algorithm_t algo
)
252 return _get_algo (&glob_ml
, algo
);
256 * gnutls_crypto_single_digest_register:
257 * @algorithm: is the gnutls algorithm identifier
258 * @priority: is the priority of the algorithm
259 * @s: is a structure holding new algorithms's data
261 * This function will register a digest (hash) algorithm to be used by
262 * gnutls. Any algorithm registered will override the included
263 * algorithms and by convention kernel implemented algorithms have
264 * priority of 90 and CPU-assisted of 80. The algorithm with the lowest priority will be
267 * This function should be called before gnutls_global_init().
269 * For simplicity you can use the convenience
270 * gnutls_crypto_single_digest_register() macro.
272 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
277 gnutls_crypto_single_digest_register (gnutls_digest_algorithm_t algorithm
,
279 const gnutls_crypto_digest_st
* s
)
281 return _algo_register (&glob_dl
, algorithm
, priority
, s
);
284 const gnutls_crypto_digest_st
*
285 _gnutls_get_crypto_digest (gnutls_digest_algorithm_t algo
)
287 return _get_algo (&glob_dl
, algo
);
291 * gnutls_crypto_bigint_register:
292 * @priority: is the priority of the interface
293 * @s: is a structure holding new interface's data
295 * This function will register an interface for gnutls to operate
296 * on big integers. Any interface registered will override
297 * the included interface. The interface with the lowest
298 * priority will be used by gnutls.
300 * Note that the bigint interface must interoperate with the public
301 * key interface. Thus if this interface is updated the
302 * gnutls_crypto_pk_register() should also be used.
304 * This function should be called before gnutls_global_init().
306 * For simplicity you can use the convenience gnutls_crypto_bigint_register()
309 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
314 gnutls_crypto_bigint_register (int priority
,
315 const gnutls_crypto_bigint_st
* s
)
317 if (crypto_bigint_prio
> priority
)
319 memcpy (&_gnutls_mpi_ops
, s
, sizeof (*s
));
320 crypto_bigint_prio
= priority
;
324 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;
328 * gnutls_crypto_pk_register:
329 * @priority: is the priority of the interface
330 * @s: is a structure holding new interface's data
332 * This function will register an interface for gnutls to operate
333 * on public key operations. Any interface registered will override
334 * the included interface. The interface with the lowest
335 * priority will be used by gnutls.
337 * Note that the bigint interface must interoperate with the bigint
338 * interface. Thus if this interface is updated the
339 * gnutls_crypto_bigint_register() should also be used.
341 * This function should be called before gnutls_global_init().
343 * For simplicity you can use the convenience gnutls_crypto_pk_register()
346 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
351 gnutls_crypto_pk_register (int priority
,
352 const gnutls_crypto_pk_st
* s
)
354 if (crypto_pk_prio
> priority
)
356 memcpy (&_gnutls_pk_ops
, s
, sizeof (*s
));
357 crypto_pk_prio
= priority
;
361 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;
365 * gnutls_crypto_cipher_register:
366 * @priority: is the priority of the cipher interface
367 * @s: is a structure holding new interface's data
369 * This function will register a cipher interface to be used by
370 * gnutls. Any interface registered will override the included engine
371 * and by convention kernel implemented interfaces should have
372 * priority of 90 and CPU-assisted of 80. The interface with the lowest priority will be used
375 * This function should be called before gnutls_global_init().
377 * For simplicity you can use the convenience
378 * gnutls_crypto_cipher_register() macro.
380 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
385 gnutls_crypto_cipher_register (int priority
,
386 const gnutls_crypto_cipher_st
* s
)
388 if (crypto_cipher_prio
> priority
)
390 memcpy (&_gnutls_cipher_ops
, s
, sizeof (*s
));
391 crypto_cipher_prio
= priority
;
395 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;
399 * gnutls_crypto_mac_register:
400 * @priority: is the priority of the mac interface
401 * @s: is a structure holding new interface's data
403 * This function will register a mac interface to be used by
404 * gnutls. Any interface registered will override the included engine
405 * and by convention kernel implemented interfaces should have
406 * priority of 90 and CPU-assisted of 80. The interface with the lowest priority will be used
409 * This function should be called before gnutls_global_init().
411 * For simplicity you can use the convenience
412 * gnutls_crypto_digest_register() macro.
414 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
419 gnutls_crypto_mac_register (int priority
,
420 const gnutls_crypto_mac_st
* s
)
422 if (crypto_mac_prio
> priority
)
424 memcpy (&_gnutls_mac_ops
, s
, sizeof (*s
));
425 crypto_mac_prio
= priority
;
429 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;
433 * gnutls_crypto_digest_register:
434 * @priority: is the priority of the digest interface
435 * @s: is a structure holding new interface's data
437 * This function will register a digest interface to be used by
438 * gnutls. Any interface registered will override the included engine
439 * and by convention kernel implemented interfaces should have
440 * priority of 90 and CPU-assisted of 80. The interface with the lowest priority will be used
443 * This function should be called before gnutls_global_init().
445 * For simplicity you can use the convenience
446 * gnutls_crypto_digest_register() macro.
448 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
453 gnutls_crypto_digest_register (int priority
,
454 const gnutls_crypto_digest_st
* s
)
456 if (crypto_digest_prio
> priority
)
458 memcpy (&_gnutls_digest_ops
, s
, sizeof (*s
));
459 crypto_digest_prio
= priority
;
463 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED
;