5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 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.
22 #include "silcincludes.h"
24 #include "ciphers.h" /* Includes cipher definitions */
26 /* Dynamically registered list of ciphers. */
27 SilcDList silc_cipher_list = NULL;
29 /* Static list of ciphers for silc_cipher_register_default(). */
30 SilcCipherObject silc_default_ciphers[] =
32 { "aes-256-cbc", 16, 256, silc_aes_set_key,
33 silc_aes_set_key_with_string, silc_aes_encrypt_cbc,
34 silc_aes_decrypt_cbc, silc_aes_context_len },
35 { "aes-192-cbc", 16, 192, silc_aes_set_key,
36 silc_aes_set_key_with_string, silc_aes_encrypt_cbc,
37 silc_aes_decrypt_cbc, silc_aes_context_len },
38 { "aes-128-cbc", 16, 128, silc_aes_set_key,
39 silc_aes_set_key_with_string, silc_aes_encrypt_cbc,
40 silc_aes_decrypt_cbc, silc_aes_context_len },
41 { "twofish-256-cbc", 16, 256, silc_twofish_set_key,
42 silc_twofish_set_key_with_string,
43 silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc,
44 silc_twofish_context_len },
45 { "twofish-192-cbc", 16, 192, silc_twofish_set_key,
46 silc_twofish_set_key_with_string,
47 silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc,
48 silc_twofish_context_len },
49 { "twofish-128-cbc", 16, 128, silc_twofish_set_key,
50 silc_twofish_set_key_with_string,
51 silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc,
52 silc_twofish_context_len },
53 { "rc6-256-cbc", 16, 256, silc_rc6_set_key, silc_rc6_set_key_with_string,
54 silc_rc6_encrypt_cbc, silc_rc6_decrypt_cbc,
55 silc_rc6_context_len },
56 { "rc6-192-cbc", 16, 192, silc_rc6_set_key, silc_rc6_set_key_with_string,
57 silc_rc6_encrypt_cbc, silc_rc6_decrypt_cbc,
58 silc_rc6_context_len },
59 { "rc6-128-cbc", 16, 128, 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-256-cbc", 16, 256, 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 { "mars-192-cbc", 16, 192, silc_mars_set_key, silc_mars_set_key_with_string,
66 silc_mars_encrypt_cbc, silc_mars_decrypt_cbc,
67 silc_mars_context_len },
68 { "mars-128-cbc", 16, 128, 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 { "cast-256-cbc", 16, 256, silc_cast_set_key, silc_cast_set_key_with_string,
72 silc_cast_encrypt_cbc, silc_cast_decrypt_cbc,
73 silc_cast_context_len },
74 { "cast-192-cbc", 16, 192, silc_cast_set_key, silc_cast_set_key_with_string,
75 silc_cast_encrypt_cbc, silc_cast_decrypt_cbc,
76 silc_cast_context_len },
77 { "cast-128-cbc", 16, 128, silc_cast_set_key, silc_cast_set_key_with_string,
78 silc_cast_encrypt_cbc, silc_cast_decrypt_cbc,
79 silc_cast_context_len },
80 { "none", 0, 0, silc_none_set_key, silc_none_set_key_with_string,
81 silc_none_encrypt_cbc, silc_none_decrypt_cbc,
82 silc_none_context_len },
84 { NULL, 0, 0, NULL, NULL, NULL, NULL, NULL }
87 /* Register a new cipher into SILC. This is used at the initialization of
88 the SILC. This function allocates a new object for the cipher to be
89 registered. Therefore, if memory has been allocated for the object sent
90 as argument it has to be free'd after this function returns succesfully. */
92 bool silc_cipher_register(SilcCipherObject *cipher)
94 SilcCipherObject *new;
96 SILC_LOG_DEBUG(("Registering new cipher `%s'", cipher->name));
98 new = silc_calloc(1, sizeof(*new));
99 new->name = strdup(cipher->name);
100 new->block_len = cipher->block_len;
101 new->key_len = cipher->key_len;
102 new->set_key = cipher->set_key;
103 new->set_key_with_string = cipher->set_key_with_string;
104 new->encrypt = cipher->encrypt;
105 new->decrypt = cipher->decrypt;
106 new->context_len = cipher->context_len;
109 if (silc_cipher_list == NULL)
110 silc_cipher_list = silc_dlist_init();
111 silc_dlist_add(silc_cipher_list, new);
116 /* Unregister a cipher from the SILC. */
118 bool silc_cipher_unregister(SilcCipherObject *cipher)
120 SilcCipherObject *entry;
122 SILC_LOG_DEBUG(("Unregistering cipher"));
124 if (!silc_cipher_list)
127 silc_dlist_start(silc_cipher_list);
128 while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
129 if (cipher == SILC_ALL_CIPHERS || entry == cipher) {
130 silc_dlist_del(silc_cipher_list, entry);
131 silc_free(entry->name);
134 if (silc_dlist_count(silc_cipher_list) == 0) {
135 silc_dlist_uninit(silc_cipher_list);
136 silc_cipher_list = NULL;
146 /* Function that registers all the default ciphers (all builtin ciphers).
147 The application may use this to register the default ciphers if specific
148 ciphers in any specific order is not wanted. */
150 bool silc_cipher_register_default(void)
154 for (i = 0; silc_default_ciphers[i].name; i++)
155 silc_cipher_register(&(silc_default_ciphers[i]));
160 /* Allocates a new SILC cipher object. Function returns 1 on succes and 0
161 on error. The allocated cipher is returned in new_cipher argument. The
162 caller must set the key to the cipher after this function has returned
163 by calling the ciphers set_key function. */
165 bool silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher)
167 SilcCipherObject *entry;
169 SILC_LOG_DEBUG(("Allocating new cipher object"));
171 if (silc_cipher_list) {
172 silc_dlist_start(silc_cipher_list);
173 while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
174 if (!strcmp(entry->name, name)) {
175 *new_cipher = silc_calloc(1, sizeof(**new_cipher));
176 (*new_cipher)->cipher = entry;
177 (*new_cipher)->context = silc_calloc(1, entry->context_len());
178 (*new_cipher)->set_iv = silc_cipher_set_iv;
179 (*new_cipher)->get_iv = silc_cipher_get_iv;
180 (*new_cipher)->get_key_len = silc_cipher_get_key_len;
181 (*new_cipher)->get_block_len = silc_cipher_get_block_len;
190 /* Free's the given cipher. */
192 void silc_cipher_free(SilcCipher cipher)
195 silc_free(cipher->context);
200 /* Returns TRUE if cipher `name' is supported. */
202 bool silc_cipher_is_supported(const unsigned char *name)
204 SilcCipherObject *entry;
206 if (silc_cipher_list) {
207 silc_dlist_start(silc_cipher_list);
208 while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
209 if (!strcmp(entry->name, name))
217 /* Returns comma separated list of supported ciphers. */
219 char *silc_cipher_get_supported(void)
221 SilcCipherObject *entry;
226 if (silc_cipher_list) {
227 silc_dlist_start(silc_cipher_list);
228 while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
229 len += strlen(entry->name);
230 list = silc_realloc(list, len + 1);
232 memcpy(list + (len - strlen(entry->name)),
233 entry->name, strlen(entry->name));
234 memcpy(list + len, ",", 1);
245 bool silc_cipher_encrypt(SilcCipher cipher, const unsigned char *src,
246 unsigned char *dst, uint32 len,
249 return cipher->cipher->encrypt(cipher->context, src, dst, len, iv);
254 bool silc_cipher_decrypt(SilcCipher cipher, const unsigned char *src,
255 unsigned char *dst, uint32 len,
258 return cipher->cipher->decrypt(cipher->context, src, dst, len, iv);
261 /* Sets the key for the cipher */
263 bool silc_cipher_set_key(SilcCipher cipher, const unsigned char *key,
266 return cipher->cipher->set_key(cipher->context, key, keylen);
269 /* Sets the IV (initial vector) for the cipher. */
271 void silc_cipher_set_iv(SilcCipher cipher, const unsigned char *iv)
273 memset(&cipher->iv, 0, sizeof(cipher->iv));
274 memcpy(&cipher->iv, iv, cipher->cipher->block_len);
277 /* Returns the IV (initial vector) of the cipher. The IV is returned
280 void silc_cipher_get_iv(SilcCipher cipher, unsigned char *iv)
282 memcpy(iv, &cipher->iv, cipher->cipher->block_len);
285 /* Returns the key length of the cipher. */
287 uint32 silc_cipher_get_key_len(SilcCipher cipher)
289 return cipher->cipher->key_len;
292 /* Returns the block size of the cipher. */
294 uint32 silc_cipher_get_block_len(SilcCipher cipher)
296 return cipher->cipher->block_len;