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.2 2000/07/05 06:08:43 priikone
24 * Global cosmetic change.
26 * Revision 1.1.1.1 2000/06/27 11:36:54 priikone
27 * Imported from internal CVS/Added Log headers.
32 #include "silcincludes.h"
34 #include "ciphers.h" /* Includes cipher definitions */
36 /* List of all ciphers in SILC. You can dynamically add new ciphers
37 into the list. At the initialization of SILC this list is filled with
38 the configured ciphers. */
39 struct SilcCipherListStruct {
40 SilcCipherObject *cipher;
41 struct SilcCipherListStruct *next;
44 /* Dynamically registered list of ciphers. */
45 struct SilcCipherListStruct *silc_cipher_list = NULL;
47 /* XXX: add the other good ciphers here as well */
49 /* Staticly declared list of ciphers. This is used if system doesn't
51 SilcCipherObject silc_cipher_builtin_list[] =
53 { "none", 0, 0, silc_none_set_key, silc_none_set_key_with_string,
54 silc_none_encrypt_cbc, silc_none_decrypt_cbc,
55 silc_none_context_len },
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 },
66 { NULL, 0, 0, NULL, NULL, NULL, NULL, NULL }
69 /* Register a new cipher into SILC. This is used at the initialization of
70 the SILC. This function allocates a new object for the cipher to be
71 registered. Therefore, if memory has been allocated for the object sent
72 as argument it has to be free'd after this function returns succesfully. */
74 int silc_cipher_register(SilcCipherObject *cipher)
76 struct SilcCipherListStruct *new, *c;
78 SILC_LOG_DEBUG(("Registering new cipher"));
80 new = silc_calloc(1, sizeof(*new));
81 new->cipher = silc_calloc(1, sizeof(*new->cipher));
83 /* Set the pointers */
84 new->cipher->name = strdup(cipher->name);
85 new->cipher->block_len = cipher->block_len;
86 new->cipher->key_len = cipher->key_len;
87 new->cipher->set_key = cipher->set_key;
88 new->cipher->set_key_with_string = cipher->set_key_with_string;
89 new->cipher->encrypt = cipher->encrypt;
90 new->cipher->decrypt = cipher->decrypt;
91 new->cipher->context_len = cipher->context_len;
94 /* Add the new cipher to the list */
95 if (!silc_cipher_list) {
96 silc_cipher_list = new;
100 c = silc_cipher_list;
112 /* Unregister a cipher from the SILC. */
114 int silc_cipher_unregister(SilcCipherObject *cipher)
116 struct SilcCipherListStruct *c, *tmp;
118 SILC_LOG_DEBUG(("Unregistering cipher"));
120 c = silc_cipher_list;
122 if (cipher == SILC_ALL_CIPHERS) {
123 /* Unregister all ciphers */
126 silc_free(c->cipher->name);
134 /* Unregister the cipher */
135 if (c->cipher == cipher) {
137 silc_free(c->cipher->name);
139 silc_cipher_list = tmp;
145 if (c->next->cipher == cipher) {
148 silc_free(c->cipher->name);
161 /* Allocates a new SILC cipher object. Function returns 1 on succes and 0
162 on error. The allocated cipher is returned in new_cipher argument. The
163 caller must set the key to the cipher after this function has returned
164 by calling the ciphers set_key function. */
166 int silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher)
168 struct SilcCipherListStruct *c;
171 SILC_LOG_DEBUG(("Allocating new cipher object"));
173 /* Allocate the new object */
174 *new_cipher = silc_calloc(1, sizeof(**new_cipher));
176 if (silc_cipher_list) {
178 c = silc_cipher_list;
180 if (!strcmp(c->cipher->name, name))
188 /* Set the pointers */
189 (*new_cipher)->cipher = c->cipher;
190 (*new_cipher)->context = silc_calloc(1, c->cipher->context_len());
191 (*new_cipher)->set_iv = silc_cipher_set_iv;
192 (*new_cipher)->get_iv = silc_cipher_get_iv;
193 (*new_cipher)->get_key_len = silc_cipher_get_key_len;
194 (*new_cipher)->get_block_len = silc_cipher_get_block_len;
201 for (i = 0; silc_cipher_builtin_list[i].name; i++)
202 if (!strcmp(silc_cipher_builtin_list[i].name, name))
205 if (silc_cipher_builtin_list[i].name == NULL) {
206 silc_free(*new_cipher);
210 /* Set the pointers */
211 (*new_cipher)->cipher = &silc_cipher_builtin_list[i];
212 (*new_cipher)->context =
213 silc_calloc(1, (*new_cipher)->cipher->context_len());
214 (*new_cipher)->set_iv = silc_cipher_set_iv;
215 (*new_cipher)->get_iv = silc_cipher_get_iv;
216 (*new_cipher)->get_key_len = silc_cipher_get_key_len;
217 (*new_cipher)->get_block_len = silc_cipher_get_block_len;
218 memset(&(*new_cipher)->iv, 0, sizeof((*new_cipher)->iv));
223 /* Free's the given cipher. */
225 void silc_cipher_free(SilcCipher cipher)
228 silc_free(cipher->context);
233 /* Returns TRUE if cipher `name' is supported. */
235 int silc_cipher_is_supported(const unsigned char *name)
237 struct SilcCipherListStruct *c;
240 if (silc_cipher_list) {
241 c = silc_cipher_list;
244 if (!strcmp(c->cipher->name, name))
250 for (i = 0; silc_cipher_builtin_list[i].name; i++)
251 if (!strcmp(silc_cipher_builtin_list[i].name, name))
257 /* Returns comma separated list of supported ciphers. */
259 char *silc_cipher_get_supported()
263 struct SilcCipherListStruct *c;
266 if (silc_cipher_list) {
267 c = silc_cipher_list;
270 len += strlen(c->cipher->name);
271 list = silc_realloc(list, len + 1);
273 memcpy(list + (len - strlen(c->cipher->name)),
274 c->cipher->name, strlen(c->cipher->name));
275 memcpy(list + len, ",", 1);
282 for (i = 0; silc_cipher_builtin_list[i].name; i++) {
283 len += strlen(silc_cipher_builtin_list[i].name);
284 list = silc_realloc(list, len + 1);
286 memcpy(list + (len - strlen(silc_cipher_builtin_list[i].name)),
287 silc_cipher_builtin_list[i].name,
288 strlen(silc_cipher_builtin_list[i].name));
289 memcpy(list + len, ",", 1);
298 /* Sets the IV (initial vector) for the cipher. */
300 void silc_cipher_set_iv(SilcCipher itself, const unsigned char *iv)
302 memset(&itself->iv, 0, sizeof(itself->iv));
303 memcpy(&itself->iv, iv, itself->cipher->block_len);
306 /* Returns the IV (initial vector) of the cipher. The IV is returned
309 void silc_cipher_get_iv(SilcCipher itself, unsigned char *iv)
311 memcpy(iv, &itself->iv, itself->cipher->block_len);
314 /* Returns the key length of the cipher. */
317 unsigned int silc_cipher_get_key_len(SilcCipher itself,
318 const unsigned char *name)
324 /* Returns the block size of the cipher. */
327 unsigned int silc_cipher_get_block_len(SilcCipher itself)