Version 2.3.13.
[gnutls.git] / lib / crypto.c
blob92b999bca82e8ff3defd4aa4066d764dd1fb6bb7
1 /*
2 * Copyright (C) 2008 Free Software Foundation
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>
30 typedef struct algo_list {
31 int algorithm;
32 int priority;
33 void* alg_data;
34 struct algo_list* next;
35 } algo_list;
37 #define cipher_list algo_list
38 #define mac_list algo_list
39 #define digest_list algo_list
40 #define rnd_list algo_list
42 static int _algo_register( algo_list* al, int algorithm, int priority, void* s)
44 algo_list* cl;
45 algo_list* last_cl = al;
47 /* look if there is any cipher with lowest priority. In that case do not add.
49 cl = al;
50 while( cl && cl->alg_data) {
51 if (cl->algorithm == algorithm) {
52 if (cl->priority < priority) {
53 gnutls_assert();
54 return GNUTLS_E_CRYPTO_ALREADY_REGISTERED;
55 } else {
56 /* the current has higher priority -> overwrite */
57 cl->algorithm = algorithm;
58 cl->priority = priority;
59 cl->alg_data = s;
60 return 0;
63 cl = cl->next;
64 if (cl) last_cl = cl;
67 cl = gnutls_malloc(sizeof(cipher_list));
69 if (cl == NULL) {
70 gnutls_assert();
71 return GNUTLS_E_MEMORY_ERROR;
74 cl->algorithm = algorithm;
75 cl->priority = priority;
76 cl->alg_data = s;
77 cl->next = NULL;
79 last_cl->next = cl;
80 return 0;
84 static void *_get_algo( algo_list* al, int algo)
86 cipher_list* cl;
88 /* look if there is any cipher with lowest priority. In that case do not add.
90 cl = al->next;
91 while( cl && cl->alg_data) {
92 if (cl->algorithm == algo) {
93 return cl->alg_data;
95 cl = cl->next;
98 return NULL;
101 static cipher_list glob_cl = { GNUTLS_CIPHER_NULL, 0, NULL, NULL };
102 static mac_list glob_ml = { GNUTLS_MAC_NULL, 0, NULL, NULL };
103 static digest_list glob_dl = { GNUTLS_MAC_NULL, 0, NULL, NULL };
104 static rnd_list glob_rnd = { 0, 0, NULL, NULL };
106 static void _deregister(algo_list* cl)
108 algo_list* next;
110 next = cl->next;
111 cl->next = NULL;
112 cl = next;
114 while( cl)
116 next = cl->next;
117 gnutls_free(cl);
118 cl = next;
122 void _gnutls_crypto_deregister(void)
124 _deregister( &glob_cl);
125 _deregister( &glob_ml);
126 _deregister( &glob_dl);
127 _deregister( &glob_rnd);
131 * gnutls_crypto_cipher_register - register a cipher algorithm
132 * @algorithm: is the gnutls algorithm identifier
133 * @priority: is the priority of the algorithm
134 * @s: is a structure holding new cipher's data
136 * This function will register a cipher algorithm to be used
137 * by gnutls. Any algorithm registered will override
138 * the included algorithms and by convention kernel implemented
139 * algorithms have priority of 90. The algorithm with the lowest
140 * priority will be used by gnutls.
142 * This function should be called before gnutls_global_init().
144 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
147 int gnutls_crypto_cipher_register( gnutls_cipher_algorithm_t algorithm, int priority, gnutls_crypto_cipher_st* s)
149 return _algo_register( &glob_cl, algorithm, priority, s);
152 gnutls_crypto_cipher_st *_gnutls_get_crypto_cipher( gnutls_cipher_algorithm_t algo)
154 return _get_algo( &glob_cl, algo);
158 * gnutls_crypto_rnd_register - register a random generator
159 * @priority: is the priority of the generator
160 * @s: is a structure holding new generator's data
162 * This function will register a random generator to be used
163 * by gnutls. Any generator registered will override
164 * the included generator and by convention kernel implemented
165 * generators have priority of 90. The generator with the lowest
166 * priority will be used by gnutls.
168 * This function should be called before gnutls_global_init().
170 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
173 int gnutls_crypto_rnd_register( int priority, gnutls_crypto_rnd_st* s)
175 return _algo_register( &glob_rnd, 1, priority, s);
178 gnutls_crypto_rnd_st *_gnutls_get_crypto_rnd()
180 return _get_algo( &glob_rnd, 1);
184 * gnutls_crypto_mac_register - register a MAC algorithm
185 * @algorithm: is the gnutls algorithm identifier
186 * @priority: is the priority of the algorithm
187 * @s: is a structure holding new algorithms's data
189 * This function will register a MAC algorithm to be used
190 * by gnutls. Any algorithm registered will override
191 * the included algorithms and by convention kernel implemented
192 * algorithms have priority of 90. The algorithm with the lowest
193 * priority will be used by gnutls.
195 * This function should be called before gnutls_global_init().
197 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
200 int gnutls_crypto_mac_register( gnutls_mac_algorithm_t algorithm, int priority, gnutls_crypto_mac_st* s)
202 return _algo_register( &glob_ml, algorithm, priority, s);
205 gnutls_crypto_mac_st *_gnutls_get_crypto_mac( gnutls_mac_algorithm_t algo)
207 return _get_algo( &glob_ml, algo);
211 * gnutls_crypto_digest_register - register a digest algorithm
212 * @algorithm: is the gnutls algorithm identifier
213 * @priority: is the priority of the algorithm
214 * @s: is a structure holding new algorithms's data
216 * This function will register a digest (hash) algorithm to be used
217 * by gnutls. Any algorithm registered will override
218 * the included algorithms and by convention kernel implemented
219 * algorithms have priority of 90. The algorithm with the lowest
220 * priority will be used by gnutls.
222 * This function should be called before gnutls_global_init().
224 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
227 int gnutls_crypto_digest_register( gnutls_digest_algorithm_t algorithm, int priority, gnutls_crypto_digest_st* s)
229 return _algo_register( &glob_dl, algorithm, priority, s);
232 gnutls_crypto_digest_st *_gnutls_get_crypto_digest( gnutls_digest_algorithm_t algo)
234 return _get_algo( &glob_dl, algo);