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);
132 if (silc_dlist_count(silc_cipher_list) == 0) {
133 silc_dlist_uninit(silc_cipher_list);
134 silc_cipher_list = NULL;
144 /* Function that registers all the default ciphers (all builtin ciphers).
145 The application may use this to register the default ciphers if specific
146 ciphers in any specific order is not wanted. */
148 bool silc_cipher_register_default(void)
152 for (i = 0; silc_default_ciphers[i].name; i++)
153 silc_cipher_register(&(silc_default_ciphers[i]));
158 /* Allocates a new SILC cipher object. Function returns 1 on succes and 0
159 on error. The allocated cipher is returned in new_cipher argument. The
160 caller must set the key to the cipher after this function has returned
161 by calling the ciphers set_key function. */
163 bool silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher)
165 SilcCipherObject *entry;
167 SILC_LOG_DEBUG(("Allocating new cipher object"));
169 if (silc_cipher_list) {
170 silc_dlist_start(silc_cipher_list);
171 while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
172 if (!strcmp(entry->name, name)) {
173 *new_cipher = silc_calloc(1, sizeof(**new_cipher));
174 (*new_cipher)->cipher = entry;
175 (*new_cipher)->context = silc_calloc(1, entry->context_len());
176 (*new_cipher)->set_iv = silc_cipher_set_iv;
177 (*new_cipher)->get_iv = silc_cipher_get_iv;
178 (*new_cipher)->get_key_len = silc_cipher_get_key_len;
179 (*new_cipher)->get_block_len = silc_cipher_get_block_len;
188 /* Free's the given cipher. */
190 void silc_cipher_free(SilcCipher cipher)
193 silc_free(cipher->context);
198 /* Returns TRUE if cipher `name' is supported. */
200 bool silc_cipher_is_supported(const unsigned char *name)
202 SilcCipherObject *entry;
204 if (silc_cipher_list) {
205 silc_dlist_start(silc_cipher_list);
206 while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
207 if (!strcmp(entry->name, name))
215 /* Returns comma separated list of supported ciphers. */
217 char *silc_cipher_get_supported(void)
219 SilcCipherObject *entry;
224 if (silc_cipher_list) {
225 silc_dlist_start(silc_cipher_list);
226 while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
227 len += strlen(entry->name);
228 list = silc_realloc(list, len + 1);
230 memcpy(list + (len - strlen(entry->name)),
231 entry->name, strlen(entry->name));
232 memcpy(list + len, ",", 1);
243 bool silc_cipher_encrypt(SilcCipher cipher, const unsigned char *src,
244 unsigned char *dst, uint32 len,
247 return cipher->cipher->encrypt(cipher->context, src, dst, len, iv);
252 bool silc_cipher_decrypt(SilcCipher cipher, const unsigned char *src,
253 unsigned char *dst, uint32 len,
256 return cipher->cipher->decrypt(cipher->context, src, dst, len, iv);
259 /* Sets the key for the cipher */
261 bool silc_cipher_set_key(SilcCipher cipher, const unsigned char *key,
264 return cipher->cipher->set_key(cipher->context, key, keylen);
267 /* Sets the IV (initial vector) for the cipher. */
269 void silc_cipher_set_iv(SilcCipher cipher, const unsigned char *iv)
271 memset(&cipher->iv, 0, sizeof(cipher->iv));
272 memcpy(&cipher->iv, iv, cipher->cipher->block_len);
275 /* Returns the IV (initial vector) of the cipher. The IV is returned
278 void silc_cipher_get_iv(SilcCipher cipher, unsigned char *iv)
280 memcpy(iv, &cipher->iv, cipher->cipher->block_len);
283 /* Returns the key length of the cipher. */
285 uint32 silc_cipher_get_key_len(SilcCipher cipher)
287 return cipher->cipher->key_len;
290 /* Returns the block size of the cipher. */
292 uint32 silc_cipher_get_block_len(SilcCipher cipher)
294 return cipher->cipher->block_len;