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.5 2000/10/09 11:37:21 priikone
24 * bugfixes. Made public/private keys protocol compliant.
26 * Revision 1.4 2000/10/02 18:31:46 priikone
27 * Added rijndael (AES) to cipher list.
29 * Revision 1.3 2000/09/28 11:28:20 priikone
30 * Changed cipher list order.
32 * Revision 1.2 2000/07/05 06:08:43 priikone
33 * Global cosmetic change.
35 * Revision 1.1.1.1 2000/06/27 11:36:54 priikone
36 * Imported from internal CVS/Added Log headers.
41 #include "silcincludes.h"
43 #include "ciphers.h" /* Includes cipher definitions */
45 /* List of all ciphers in SILC. You can dynamically add new ciphers
46 into the list. At the initialization of SILC this list is filled with
47 the configured ciphers. */
48 struct SilcCipherListStruct {
49 SilcCipherObject *cipher;
50 struct SilcCipherListStruct *next;
53 /* Dynamically registered list of ciphers. */
54 struct SilcCipherListStruct *silc_cipher_list = NULL;
56 /* XXX: add the other good ciphers here as well */
58 /* Staticly declared list of ciphers. This is used if system doesn't
60 SilcCipherObject silc_cipher_builtin_list[] =
62 { "twofish", 16, 16, silc_twofish_set_key, silc_twofish_set_key_with_string,
63 silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc,
64 silc_twofish_context_len },
65 { "aes", 16, 16, silc_rijndael_set_key,
66 silc_rijndael_set_key_with_string, silc_rijndael_encrypt_cbc,
67 silc_rijndael_decrypt_cbc, silc_rijndael_context_len },
68 { "rc6", 16, 16, silc_rc6_set_key, silc_rc6_set_key_with_string,
69 silc_rc6_encrypt_cbc, silc_rc6_decrypt_cbc,
70 silc_rc6_context_len },
71 { "mars", 16, 16, silc_mars_set_key, silc_mars_set_key_with_string,
72 silc_mars_encrypt_cbc, silc_mars_decrypt_cbc,
73 silc_mars_context_len },
74 { "none", 0, 0, silc_none_set_key, silc_none_set_key_with_string,
75 silc_none_encrypt_cbc, silc_none_decrypt_cbc,
76 silc_none_context_len },
78 { NULL, 0, 0, NULL, NULL, NULL, NULL, NULL }
81 /* Register a new cipher into SILC. This is used at the initialization of
82 the SILC. This function allocates a new object for the cipher to be
83 registered. Therefore, if memory has been allocated for the object sent
84 as argument it has to be free'd after this function returns succesfully. */
86 int silc_cipher_register(SilcCipherObject *cipher)
88 struct SilcCipherListStruct *new, *c;
90 SILC_LOG_DEBUG(("Registering new cipher"));
92 new = silc_calloc(1, sizeof(*new));
93 new->cipher = silc_calloc(1, sizeof(*new->cipher));
95 /* Set the pointers */
96 new->cipher->name = strdup(cipher->name);
97 new->cipher->block_len = cipher->block_len;
98 new->cipher->key_len = cipher->key_len;
99 new->cipher->set_key = cipher->set_key;
100 new->cipher->set_key_with_string = cipher->set_key_with_string;
101 new->cipher->encrypt = cipher->encrypt;
102 new->cipher->decrypt = cipher->decrypt;
103 new->cipher->context_len = cipher->context_len;
106 /* Add the new cipher to the list */
107 if (!silc_cipher_list) {
108 silc_cipher_list = new;
112 c = silc_cipher_list;
124 /* Unregister a cipher from the SILC. */
126 int silc_cipher_unregister(SilcCipherObject *cipher)
128 struct SilcCipherListStruct *c, *tmp;
130 SILC_LOG_DEBUG(("Unregistering cipher"));
132 c = silc_cipher_list;
134 if (cipher == SILC_ALL_CIPHERS) {
135 /* Unregister all ciphers */
138 silc_free(c->cipher->name);
146 /* Unregister the cipher */
147 if (c->cipher == cipher) {
149 silc_free(c->cipher->name);
151 silc_cipher_list = tmp;
157 if (c->next->cipher == cipher) {
160 silc_free(c->cipher->name);
173 /* Allocates a new SILC cipher object. Function returns 1 on succes and 0
174 on error. The allocated cipher is returned in new_cipher argument. The
175 caller must set the key to the cipher after this function has returned
176 by calling the ciphers set_key function. */
178 int silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher)
180 struct SilcCipherListStruct *c;
183 SILC_LOG_DEBUG(("Allocating new cipher object"));
185 /* Allocate the new object */
186 *new_cipher = silc_calloc(1, sizeof(**new_cipher));
188 if (silc_cipher_list) {
190 c = silc_cipher_list;
192 if (!strcmp(c->cipher->name, name))
200 /* Set the pointers */
201 (*new_cipher)->cipher = c->cipher;
202 (*new_cipher)->context = silc_calloc(1, c->cipher->context_len());
203 (*new_cipher)->set_iv = silc_cipher_set_iv;
204 (*new_cipher)->get_iv = silc_cipher_get_iv;
205 (*new_cipher)->get_key_len = silc_cipher_get_key_len;
206 (*new_cipher)->get_block_len = silc_cipher_get_block_len;
213 for (i = 0; silc_cipher_builtin_list[i].name; i++)
214 if (!strcmp(silc_cipher_builtin_list[i].name, name))
217 if (silc_cipher_builtin_list[i].name == NULL) {
218 silc_free(*new_cipher);
222 /* Set the pointers */
223 (*new_cipher)->cipher = &silc_cipher_builtin_list[i];
224 (*new_cipher)->context =
225 silc_calloc(1, (*new_cipher)->cipher->context_len());
226 (*new_cipher)->set_iv = silc_cipher_set_iv;
227 (*new_cipher)->get_iv = silc_cipher_get_iv;
228 (*new_cipher)->get_key_len = silc_cipher_get_key_len;
229 (*new_cipher)->get_block_len = silc_cipher_get_block_len;
230 memset(&(*new_cipher)->iv, 0, sizeof((*new_cipher)->iv));
235 /* Free's the given cipher. */
237 void silc_cipher_free(SilcCipher cipher)
240 silc_free(cipher->context);
245 /* Returns TRUE if cipher `name' is supported. */
247 int silc_cipher_is_supported(const unsigned char *name)
249 struct SilcCipherListStruct *c;
252 if (silc_cipher_list) {
253 c = silc_cipher_list;
256 if (!strcmp(c->cipher->name, name))
262 for (i = 0; silc_cipher_builtin_list[i].name; i++)
263 if (!strcmp(silc_cipher_builtin_list[i].name, name))
269 /* Returns comma separated list of supported ciphers. */
271 char *silc_cipher_get_supported()
275 struct SilcCipherListStruct *c;
278 if (silc_cipher_list) {
279 c = silc_cipher_list;
282 len += strlen(c->cipher->name);
283 list = silc_realloc(list, len + 1);
285 memcpy(list + (len - strlen(c->cipher->name)),
286 c->cipher->name, strlen(c->cipher->name));
287 memcpy(list + len, ",", 1);
294 for (i = 0; silc_cipher_builtin_list[i].name; i++) {
295 len += strlen(silc_cipher_builtin_list[i].name);
296 list = silc_realloc(list, len + 1);
298 memcpy(list + (len - strlen(silc_cipher_builtin_list[i].name)),
299 silc_cipher_builtin_list[i].name,
300 strlen(silc_cipher_builtin_list[i].name));
301 memcpy(list + len, ",", 1);
310 /* Sets the IV (initial vector) for the cipher. */
312 void silc_cipher_set_iv(SilcCipher itself, const unsigned char *iv)
314 memset(&itself->iv, 0, sizeof(itself->iv));
315 memcpy(&itself->iv, iv, itself->cipher->block_len);
318 /* Returns the IV (initial vector) of the cipher. The IV is returned
321 void silc_cipher_get_iv(SilcCipher itself, unsigned char *iv)
323 memcpy(iv, &itself->iv, itself->cipher->block_len);
326 /* Returns the key length of the cipher. */
329 unsigned int silc_cipher_get_key_len(SilcCipher itself,
330 const unsigned char *name)
336 /* Returns the block size of the cipher. */
339 unsigned int silc_cipher_get_block_len(SilcCipher itself)