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.4 2000/10/02 18:31:46 priikone
24 * Added rijndael (AES) to cipher list.
26 * Revision 1.3 2000/09/28 11:28:20 priikone
27 * Changed cipher list order.
29 * Revision 1.2 2000/07/05 06:08:43 priikone
30 * Global cosmetic change.
32 * Revision 1.1.1.1 2000/06/27 11:36:54 priikone
33 * Imported from internal CVS/Added Log headers.
38 #include "silcincludes.h"
40 #include "ciphers.h" /* Includes cipher definitions */
42 /* List of all ciphers in SILC. You can dynamically add new ciphers
43 into the list. At the initialization of SILC this list is filled with
44 the configured ciphers. */
45 struct SilcCipherListStruct {
46 SilcCipherObject *cipher;
47 struct SilcCipherListStruct *next;
50 /* Dynamically registered list of ciphers. */
51 struct SilcCipherListStruct *silc_cipher_list = NULL;
53 /* XXX: add the other good ciphers here as well */
55 /* Staticly declared list of ciphers. This is used if system doesn't
57 SilcCipherObject silc_cipher_builtin_list[] =
59 { "twofish", 16, 16, silc_twofish_set_key, silc_twofish_set_key_with_string,
60 silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc,
61 silc_twofish_context_len },
62 { "rijndael", 16, 16, silc_rijndael_set_key,
63 silc_rijndael_set_key_with_string, silc_rijndael_encrypt_cbc,
64 silc_rijndael_decrypt_cbc, silc_rijndael_context_len },
65 { "rc6", 16, 16, silc_rc6_set_key, silc_rc6_set_key_with_string,
66 silc_rc6_encrypt_cbc, silc_rc6_decrypt_cbc,
67 silc_rc6_context_len },
68 { "mars", 16, 16, silc_mars_set_key, silc_mars_set_key_with_string,
69 silc_mars_encrypt_cbc, silc_mars_decrypt_cbc,
70 silc_mars_context_len },
71 { "none", 0, 0, silc_none_set_key, silc_none_set_key_with_string,
72 silc_none_encrypt_cbc, silc_none_decrypt_cbc,
73 silc_none_context_len },
75 { NULL, 0, 0, NULL, NULL, NULL, NULL, NULL }
78 /* Register a new cipher into SILC. This is used at the initialization of
79 the SILC. This function allocates a new object for the cipher to be
80 registered. Therefore, if memory has been allocated for the object sent
81 as argument it has to be free'd after this function returns succesfully. */
83 int silc_cipher_register(SilcCipherObject *cipher)
85 struct SilcCipherListStruct *new, *c;
87 SILC_LOG_DEBUG(("Registering new cipher"));
89 new = silc_calloc(1, sizeof(*new));
90 new->cipher = silc_calloc(1, sizeof(*new->cipher));
92 /* Set the pointers */
93 new->cipher->name = strdup(cipher->name);
94 new->cipher->block_len = cipher->block_len;
95 new->cipher->key_len = cipher->key_len;
96 new->cipher->set_key = cipher->set_key;
97 new->cipher->set_key_with_string = cipher->set_key_with_string;
98 new->cipher->encrypt = cipher->encrypt;
99 new->cipher->decrypt = cipher->decrypt;
100 new->cipher->context_len = cipher->context_len;
103 /* Add the new cipher to the list */
104 if (!silc_cipher_list) {
105 silc_cipher_list = new;
109 c = silc_cipher_list;
121 /* Unregister a cipher from the SILC. */
123 int silc_cipher_unregister(SilcCipherObject *cipher)
125 struct SilcCipherListStruct *c, *tmp;
127 SILC_LOG_DEBUG(("Unregistering cipher"));
129 c = silc_cipher_list;
131 if (cipher == SILC_ALL_CIPHERS) {
132 /* Unregister all ciphers */
135 silc_free(c->cipher->name);
143 /* Unregister the cipher */
144 if (c->cipher == cipher) {
146 silc_free(c->cipher->name);
148 silc_cipher_list = tmp;
154 if (c->next->cipher == cipher) {
157 silc_free(c->cipher->name);
170 /* Allocates a new SILC cipher object. Function returns 1 on succes and 0
171 on error. The allocated cipher is returned in new_cipher argument. The
172 caller must set the key to the cipher after this function has returned
173 by calling the ciphers set_key function. */
175 int silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher)
177 struct SilcCipherListStruct *c;
180 SILC_LOG_DEBUG(("Allocating new cipher object"));
182 /* Allocate the new object */
183 *new_cipher = silc_calloc(1, sizeof(**new_cipher));
185 if (silc_cipher_list) {
187 c = silc_cipher_list;
189 if (!strcmp(c->cipher->name, name))
197 /* Set the pointers */
198 (*new_cipher)->cipher = c->cipher;
199 (*new_cipher)->context = silc_calloc(1, c->cipher->context_len());
200 (*new_cipher)->set_iv = silc_cipher_set_iv;
201 (*new_cipher)->get_iv = silc_cipher_get_iv;
202 (*new_cipher)->get_key_len = silc_cipher_get_key_len;
203 (*new_cipher)->get_block_len = silc_cipher_get_block_len;
210 for (i = 0; silc_cipher_builtin_list[i].name; i++)
211 if (!strcmp(silc_cipher_builtin_list[i].name, name))
214 if (silc_cipher_builtin_list[i].name == NULL) {
215 silc_free(*new_cipher);
219 /* Set the pointers */
220 (*new_cipher)->cipher = &silc_cipher_builtin_list[i];
221 (*new_cipher)->context =
222 silc_calloc(1, (*new_cipher)->cipher->context_len());
223 (*new_cipher)->set_iv = silc_cipher_set_iv;
224 (*new_cipher)->get_iv = silc_cipher_get_iv;
225 (*new_cipher)->get_key_len = silc_cipher_get_key_len;
226 (*new_cipher)->get_block_len = silc_cipher_get_block_len;
227 memset(&(*new_cipher)->iv, 0, sizeof((*new_cipher)->iv));
232 /* Free's the given cipher. */
234 void silc_cipher_free(SilcCipher cipher)
237 silc_free(cipher->context);
242 /* Returns TRUE if cipher `name' is supported. */
244 int silc_cipher_is_supported(const unsigned char *name)
246 struct SilcCipherListStruct *c;
249 if (silc_cipher_list) {
250 c = silc_cipher_list;
253 if (!strcmp(c->cipher->name, name))
259 for (i = 0; silc_cipher_builtin_list[i].name; i++)
260 if (!strcmp(silc_cipher_builtin_list[i].name, name))
266 /* Returns comma separated list of supported ciphers. */
268 char *silc_cipher_get_supported()
272 struct SilcCipherListStruct *c;
275 if (silc_cipher_list) {
276 c = silc_cipher_list;
279 len += strlen(c->cipher->name);
280 list = silc_realloc(list, len + 1);
282 memcpy(list + (len - strlen(c->cipher->name)),
283 c->cipher->name, strlen(c->cipher->name));
284 memcpy(list + len, ",", 1);
291 for (i = 0; silc_cipher_builtin_list[i].name; i++) {
292 len += strlen(silc_cipher_builtin_list[i].name);
293 list = silc_realloc(list, len + 1);
295 memcpy(list + (len - strlen(silc_cipher_builtin_list[i].name)),
296 silc_cipher_builtin_list[i].name,
297 strlen(silc_cipher_builtin_list[i].name));
298 memcpy(list + len, ",", 1);
307 /* Sets the IV (initial vector) for the cipher. */
309 void silc_cipher_set_iv(SilcCipher itself, const unsigned char *iv)
311 memset(&itself->iv, 0, sizeof(itself->iv));
312 memcpy(&itself->iv, iv, itself->cipher->block_len);
315 /* Returns the IV (initial vector) of the cipher. The IV is returned
318 void silc_cipher_get_iv(SilcCipher itself, unsigned char *iv)
320 memcpy(iv, &itself->iv, itself->cipher->block_len);
323 /* Returns the key length of the cipher. */
326 unsigned int silc_cipher_get_key_len(SilcCipher itself,
327 const unsigned char *name)
333 /* Returns the block size of the cipher. */
336 unsigned int silc_cipher_get_block_len(SilcCipher itself)