5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
23 * Revision 1.3 2000/09/28 11:28:20 priikone
24 * Changed cipher list order.
26 * Revision 1.2 2000/07/05 06:08:43 priikone
27 * Global cosmetic change.
29 * Revision 1.1.1.1 2000/06/27 11:36:54 priikone
30 * Imported from internal CVS/Added Log headers.
35 #include "silcincludes.h"
37 #include "ciphers.h" /* Includes cipher definitions */
39 /* List of all ciphers in SILC. You can dynamically add new ciphers
40 into the list. At the initialization of SILC this list is filled with
41 the configured ciphers. */
42 struct SilcCipherListStruct {
43 SilcCipherObject *cipher;
44 struct SilcCipherListStruct *next;
47 /* Dynamically registered list of ciphers. */
48 struct SilcCipherListStruct *silc_cipher_list = NULL;
50 /* XXX: add the other good ciphers here as well */
52 /* Staticly declared list of ciphers. This is used if system doesn't
54 SilcCipherObject silc_cipher_builtin_list[] =
56 { "twofish", 16, 16, silc_twofish_set_key, silc_twofish_set_key_with_string,
57 silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc,
58 silc_twofish_context_len },
59 { "rc6", 16, 16, silc_rc6_set_key, silc_rc6_set_key_with_string,
60 silc_rc6_encrypt_cbc, silc_rc6_decrypt_cbc,
61 silc_rc6_context_len },
62 { "mars", 16, 16, silc_mars_set_key, silc_mars_set_key_with_string,
63 silc_mars_encrypt_cbc, silc_mars_decrypt_cbc,
64 silc_mars_context_len },
65 { "none", 0, 0, silc_none_set_key, silc_none_set_key_with_string,
66 silc_none_encrypt_cbc, silc_none_decrypt_cbc,
67 silc_none_context_len },
69 { NULL, 0, 0, NULL, NULL, NULL, NULL, NULL }
72 /* Register a new cipher into SILC. This is used at the initialization of
73 the SILC. This function allocates a new object for the cipher to be
74 registered. Therefore, if memory has been allocated for the object sent
75 as argument it has to be free'd after this function returns succesfully. */
77 int silc_cipher_register(SilcCipherObject *cipher)
79 struct SilcCipherListStruct *new, *c;
81 SILC_LOG_DEBUG(("Registering new cipher"));
83 new = silc_calloc(1, sizeof(*new));
84 new->cipher = silc_calloc(1, sizeof(*new->cipher));
86 /* Set the pointers */
87 new->cipher->name = strdup(cipher->name);
88 new->cipher->block_len = cipher->block_len;
89 new->cipher->key_len = cipher->key_len;
90 new->cipher->set_key = cipher->set_key;
91 new->cipher->set_key_with_string = cipher->set_key_with_string;
92 new->cipher->encrypt = cipher->encrypt;
93 new->cipher->decrypt = cipher->decrypt;
94 new->cipher->context_len = cipher->context_len;
97 /* Add the new cipher to the list */
98 if (!silc_cipher_list) {
99 silc_cipher_list = new;
103 c = silc_cipher_list;
115 /* Unregister a cipher from the SILC. */
117 int silc_cipher_unregister(SilcCipherObject *cipher)
119 struct SilcCipherListStruct *c, *tmp;
121 SILC_LOG_DEBUG(("Unregistering cipher"));
123 c = silc_cipher_list;
125 if (cipher == SILC_ALL_CIPHERS) {
126 /* Unregister all ciphers */
129 silc_free(c->cipher->name);
137 /* Unregister the cipher */
138 if (c->cipher == cipher) {
140 silc_free(c->cipher->name);
142 silc_cipher_list = tmp;
148 if (c->next->cipher == cipher) {
151 silc_free(c->cipher->name);
164 /* Allocates a new SILC cipher object. Function returns 1 on succes and 0
165 on error. The allocated cipher is returned in new_cipher argument. The
166 caller must set the key to the cipher after this function has returned
167 by calling the ciphers set_key function. */
169 int silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher)
171 struct SilcCipherListStruct *c;
174 SILC_LOG_DEBUG(("Allocating new cipher object"));
176 /* Allocate the new object */
177 *new_cipher = silc_calloc(1, sizeof(**new_cipher));
179 if (silc_cipher_list) {
181 c = silc_cipher_list;
183 if (!strcmp(c->cipher->name, name))
191 /* Set the pointers */
192 (*new_cipher)->cipher = c->cipher;
193 (*new_cipher)->context = silc_calloc(1, c->cipher->context_len());
194 (*new_cipher)->set_iv = silc_cipher_set_iv;
195 (*new_cipher)->get_iv = silc_cipher_get_iv;
196 (*new_cipher)->get_key_len = silc_cipher_get_key_len;
197 (*new_cipher)->get_block_len = silc_cipher_get_block_len;
204 for (i = 0; silc_cipher_builtin_list[i].name; i++)
205 if (!strcmp(silc_cipher_builtin_list[i].name, name))
208 if (silc_cipher_builtin_list[i].name == NULL) {
209 silc_free(*new_cipher);
213 /* Set the pointers */
214 (*new_cipher)->cipher = &silc_cipher_builtin_list[i];
215 (*new_cipher)->context =
216 silc_calloc(1, (*new_cipher)->cipher->context_len());
217 (*new_cipher)->set_iv = silc_cipher_set_iv;
218 (*new_cipher)->get_iv = silc_cipher_get_iv;
219 (*new_cipher)->get_key_len = silc_cipher_get_key_len;
220 (*new_cipher)->get_block_len = silc_cipher_get_block_len;
221 memset(&(*new_cipher)->iv, 0, sizeof((*new_cipher)->iv));
226 /* Free's the given cipher. */
228 void silc_cipher_free(SilcCipher cipher)
231 silc_free(cipher->context);
236 /* Returns TRUE if cipher `name' is supported. */
238 int silc_cipher_is_supported(const unsigned char *name)
240 struct SilcCipherListStruct *c;
243 if (silc_cipher_list) {
244 c = silc_cipher_list;
247 if (!strcmp(c->cipher->name, name))
253 for (i = 0; silc_cipher_builtin_list[i].name; i++)
254 if (!strcmp(silc_cipher_builtin_list[i].name, name))
260 /* Returns comma separated list of supported ciphers. */
262 char *silc_cipher_get_supported()
266 struct SilcCipherListStruct *c;
269 if (silc_cipher_list) {
270 c = silc_cipher_list;
273 len += strlen(c->cipher->name);
274 list = silc_realloc(list, len + 1);
276 memcpy(list + (len - strlen(c->cipher->name)),
277 c->cipher->name, strlen(c->cipher->name));
278 memcpy(list + len, ",", 1);
285 for (i = 0; silc_cipher_builtin_list[i].name; i++) {
286 len += strlen(silc_cipher_builtin_list[i].name);
287 list = silc_realloc(list, len + 1);
289 memcpy(list + (len - strlen(silc_cipher_builtin_list[i].name)),
290 silc_cipher_builtin_list[i].name,
291 strlen(silc_cipher_builtin_list[i].name));
292 memcpy(list + len, ",", 1);
301 /* Sets the IV (initial vector) for the cipher. */
303 void silc_cipher_set_iv(SilcCipher itself, const unsigned char *iv)
305 memset(&itself->iv, 0, sizeof(itself->iv));
306 memcpy(&itself->iv, iv, itself->cipher->block_len);
309 /* Returns the IV (initial vector) of the cipher. The IV is returned
312 void silc_cipher_get_iv(SilcCipher itself, unsigned char *iv)
314 memcpy(iv, &itself->iv, itself->cipher->block_len);
317 /* Returns the key length of the cipher. */
320 unsigned int silc_cipher_get_key_len(SilcCipher itself,
321 const unsigned char *name)
327 /* Returns the block size of the cipher. */
330 unsigned int silc_cipher_get_block_len(SilcCipher itself)