Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2007 Pekka Riikonen
+ Copyright (C) 1997 - 2008 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
GNU General Public License for more details.
*/
-/* $Id$ */
-#include "silc.h"
+#include "silccrypto.h"
#include "ciphers.h" /* Includes cipher definitions */
-/* The SilcCipher context */
-struct SilcCipherStruct {
- SilcCipherObject *cipher;
- void *context;
- unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
-};
-
#ifndef SILC_SYMBIAN
/* Dynamically registered list of ciphers. */
SilcDList silc_cipher_list = NULL;
#endif /* SILC_SYMBIAN */
/* Macro to define cipher to cipher list */
-#define SILC_CIPHER_API_DEF(name, cipher, keylen, blocklen, ivlen, mode) \
-{ name, silc_##cipher##_set_key, silc_##cipher##_set_iv, \
+#define SILC_CDEF(name, alg_name, cipher, keylen, blocklen, ivlen, mode)\
+{ name, alg_name, silc_##cipher##_set_key, silc_##cipher##_set_iv, \
silc_##cipher##_encrypt, silc_##cipher##_decrypt, \
- silc_##cipher##_context_len, keylen, blocklen, ivlen, mode }
+ silc_##cipher##_init, silc_##cipher##_uninit, keylen, blocklen, ivlen, mode }
/* Static list of ciphers for silc_cipher_register_default(). */
const SilcCipherObject silc_default_ciphers[] =
{
- SILC_CIPHER_API_DEF("aes-256-ctr", aes_ctr, 256, 16, 16,
- SILC_CIPHER_MODE_CTR),
- SILC_CIPHER_API_DEF("aes-192-ctr", aes_ctr, 192, 16, 16,
- SILC_CIPHER_MODE_CTR),
- SILC_CIPHER_API_DEF("aes-128-ctr", aes_ctr, 128, 16, 16,
- SILC_CIPHER_MODE_CTR),
- SILC_CIPHER_API_DEF("aes-256-cbc", aes_cbc, 256, 16, 16,
- SILC_CIPHER_MODE_CBC),
- SILC_CIPHER_API_DEF("aes-192-cbc", aes_cbc, 192, 16, 16,
- SILC_CIPHER_MODE_CBC),
- SILC_CIPHER_API_DEF("aes-128-cbc", aes_cbc, 128, 16, 16,
- SILC_CIPHER_MODE_CBC),
- SILC_CIPHER_API_DEF("twofish-256-cbc", twofish_cbc, 256, 16, 16,
- SILC_CIPHER_MODE_CBC),
- SILC_CIPHER_API_DEF("twofish-192-cbc", twofish_cbc, 192, 16, 16,
- SILC_CIPHER_MODE_CBC),
- SILC_CIPHER_API_DEF("twofish-128-cbc", twofish_cbc, 128, 16, 16,
- SILC_CIPHER_MODE_CBC),
+ SILC_CDEF("aes-256-ctr", "aes", aes, 256, 16, 16, SILC_CIPHER_MODE_CTR),
+ SILC_CDEF("aes-192-ctr", "aes", aes, 192, 16, 16, SILC_CIPHER_MODE_CTR),
+ SILC_CDEF("aes-128-ctr", "aes", aes, 128, 16, 16, SILC_CIPHER_MODE_CTR),
+ SILC_CDEF("aes-256-cbc", "aes", aes, 256, 16, 16, SILC_CIPHER_MODE_CBC),
+ SILC_CDEF("aes-192-cbc", "aes", aes, 192, 16, 16, SILC_CIPHER_MODE_CBC),
+ SILC_CDEF("aes-128-cbc", "aes", aes, 128, 16, 16, SILC_CIPHER_MODE_CBC),
+ SILC_CDEF("aes-256-cfb", "aes", aes, 256, 16, 16, SILC_CIPHER_MODE_CFB),
+ SILC_CDEF("aes-192-cfb", "aes", aes, 192, 16, 16, SILC_CIPHER_MODE_CFB),
+ SILC_CDEF("aes-128-cfb", "aes", aes, 128, 16, 16, SILC_CIPHER_MODE_CFB),
+ SILC_CDEF("aes-256-ecb", "aes", aes, 256, 16, 16, SILC_CIPHER_MODE_ECB),
+ SILC_CDEF("aes-192-ecb", "aes", aes, 192, 16, 16, SILC_CIPHER_MODE_ECB),
+ SILC_CDEF("aes-128-ecb", "aes", aes, 128, 16, 16, SILC_CIPHER_MODE_ECB),
+ SILC_CDEF("twofish-256-ctr", "twofish", twofish, 256, 16, 16, SILC_CIPHER_MODE_CTR),
+ SILC_CDEF("twofish-192-ctr", "twofish", twofish, 192, 16, 16, SILC_CIPHER_MODE_CTR),
+ SILC_CDEF("twofish-128-ctr", "twofish", twofish, 128, 16, 16, SILC_CIPHER_MODE_CTR),
+ SILC_CDEF("twofish-256-cbc", "twofish", twofish, 256, 16, 16, SILC_CIPHER_MODE_CBC),
+ SILC_CDEF("twofish-192-cbc", "twofish", twofish, 192, 16, 16, SILC_CIPHER_MODE_CBC),
+ SILC_CDEF("twofish-128-cbc", "twofish", twofish, 128, 16, 16, SILC_CIPHER_MODE_CBC),
+ SILC_CDEF("twofish-256-cfb", "twofish", twofish, 256, 16, 16, SILC_CIPHER_MODE_CFB),
+ SILC_CDEF("twofish-192-cfb", "twofish", twofish, 192, 16, 16, SILC_CIPHER_MODE_CFB),
+ SILC_CDEF("twofish-128-cfb", "twofish", twofish, 128, 16, 16, SILC_CIPHER_MODE_CFB),
+ SILC_CDEF("twofish-256-ecb", "twofish", twofish, 256, 16, 16, SILC_CIPHER_MODE_ECB),
+ SILC_CDEF("twofish-192-ecb", "twofish", twofish, 192, 16, 16, SILC_CIPHER_MODE_ECB),
+ SILC_CDEF("twofish-128-ecb", "twofish", twofish, 128, 16, 16, SILC_CIPHER_MODE_ECB),
+ SILC_CDEF("cast5-128-ctr", "cast5", cast5, 128, 8, 8, SILC_CIPHER_MODE_CTR),
+ SILC_CDEF("cast5-128-cbc", "cast5", cast5, 128, 8, 8, SILC_CIPHER_MODE_CBC),
+ SILC_CDEF("cast5-128-cfb", "cast5", cast5, 128, 8, 8, SILC_CIPHER_MODE_CFB),
+ SILC_CDEF("cast5-128-ecb", "cast5", cast5, 128, 8, 8, SILC_CIPHER_MODE_ECB),
+ SILC_CDEF("des-56-ctr", "des", des, 56, 8, 8, SILC_CIPHER_MODE_CTR),
+ SILC_CDEF("des-56-cbc", "des", des, 56, 8, 8, SILC_CIPHER_MODE_CBC),
+ SILC_CDEF("des-56-cfb", "des", des, 56, 8, 8, SILC_CIPHER_MODE_CFB),
+ SILC_CDEF("des-56-ecb", "des", des, 56, 8, 8, SILC_CIPHER_MODE_ECB),
+ SILC_CDEF("3des-168-ctr", "3des", 3des, 168, 8, 8, SILC_CIPHER_MODE_CTR),
+ SILC_CDEF("3des-168-cbc", "3des", 3des, 168, 8, 8, SILC_CIPHER_MODE_CBC),
+ SILC_CDEF("3des-168-cfb", "3des", 3des, 168, 8, 8, SILC_CIPHER_MODE_CFB),
+ SILC_CDEF("3des-168-ecb", "3des", 3des, 168, 8, 8, SILC_CIPHER_MODE_ECB),
#ifdef SILC_DEBUG
- SILC_CIPHER_API_DEF("none", none, 0, 0, 0, 0),
+ SILC_CDEF("none", "none", none, 0, 0, 0, 0),
#endif /* SILC_DEBUG */
- { NULL, NULL, 0, 0, 0, 0 }
+ { NULL, NULL, NULL, 0, 0, 0, 0 }
};
/* Register new cipher */
new->set_iv = cipher->set_iv;
new->encrypt = cipher->encrypt;
new->decrypt = cipher->decrypt;
- new->context_len = cipher->context_len;
+ new->init = cipher->init;
+ new->uninit = cipher->uninit;
new->mode = cipher->mode;
/* Add to list */
caller must set the key to the cipher after this function has returned
by calling the ciphers set_key function. */
-SilcBool silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher)
+SilcBool silc_cipher_alloc(const char *name, SilcCipher *new_cipher)
{
SilcCipherObject *entry = NULL;
int i;
if (!(*new_cipher))
return FALSE;
(*new_cipher)->cipher = entry;
- (*new_cipher)->context = silc_calloc(1, entry->context_len());
+ (*new_cipher)->context = entry->init(entry);
if (!(*new_cipher)->context) {
silc_free(*new_cipher);
return FALSE;
return FALSE;
}
+/* Allocate cipher */
+
+SilcBool silc_cipher_alloc_full(const char *alg_name, SilcUInt32 key_len,
+ SilcCipherMode mode, SilcCipher *new_cipher)
+{
+ char name[64];
+ const char *mode_name;
+
+ switch (mode) {
+ case SILC_CIPHER_MODE_ECB:
+ mode_name = "ecb";
+ break;
+ case SILC_CIPHER_MODE_CBC:
+ mode_name = "cbc";
+ break;
+ case SILC_CIPHER_MODE_CTR:
+ mode_name = "ctr";
+ break;
+ case SILC_CIPHER_MODE_CFB:
+ mode_name = "cfb";
+ break;
+ case SILC_CIPHER_MODE_OFB:
+ mode_name = "ofb";
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+
+ silc_snprintf(name, sizeof(name), "%s-%d-%s", alg_name, key_len, mode_name);
+
+ return silc_cipher_alloc(name, new_cipher);
+}
+
/* Free's the given cipher. */
void silc_cipher_free(SilcCipher cipher)
{
if (cipher) {
- silc_free(cipher->context);
+ cipher->cipher->uninit(cipher->cipher, cipher->context);
+ memset(cipher, 0, sizeof(*cipher));
silc_free(cipher);
}
}
/* Returns TRUE if cipher `name' is supported. */
-SilcBool silc_cipher_is_supported(const unsigned char *name)
+SilcBool silc_cipher_is_supported(const char *name)
{
SilcCipherObject *entry;
int i;
/* Returns comma separated list of supported ciphers. */
-char *silc_cipher_get_supported(void)
+char *silc_cipher_get_supported(SilcBool only_registered)
{
SilcCipherObject *entry, *entry2;
char *list = NULL;
}
#endif /* SILC_SYMBIAN */
- for (i = 0; silc_default_ciphers[i].name; i++) {
- entry = (SilcCipherObject *)&(silc_default_ciphers[i]);
-
- if (silc_cipher_list) {
- silc_dlist_start(silc_cipher_list);
- while ((entry2 = silc_dlist_get(silc_cipher_list))) {
- if (!strcmp(entry2->name, entry->name))
- break;
+ if (!only_registered || !silc_cipher_list) {
+ for (i = 0; silc_default_ciphers[i].name; i++) {
+ entry = (SilcCipherObject *)&(silc_default_ciphers[i]);
+
+ if (silc_cipher_list) {
+ silc_dlist_start(silc_cipher_list);
+ while ((entry2 = silc_dlist_get(silc_cipher_list))) {
+ if (!strcmp(entry2->name, entry->name))
+ break;
+ }
+ if (entry2)
+ continue;
}
- if (entry2)
- continue;
- }
- len += strlen(entry->name);
- list = silc_realloc(list, len + 1);
+ len += strlen(entry->name);
+ list = silc_realloc(list, len + 1);
- memcpy(list + (len - strlen(entry->name)),
- entry->name, strlen(entry->name));
- memcpy(list + len, ",", 1);
- len++;
+ memcpy(list + (len - strlen(entry->name)),
+ entry->name, strlen(entry->name));
+ memcpy(list + len, ",", 1);
+ len++;
+ }
}
list[len - 1] = 0;
unsigned char *dst, SilcUInt32 len,
unsigned char *iv)
{
- return cipher->cipher->encrypt(cipher->context, src, dst, len,
+ return cipher->cipher->encrypt(cipher, cipher->cipher,
+ cipher->context, src, dst, len,
iv ? iv : cipher->iv);
}
unsigned char *dst, SilcUInt32 len,
unsigned char *iv)
{
- return cipher->cipher->decrypt(cipher->context, src, dst, len,
+ return cipher->cipher->decrypt(cipher, cipher->cipher,
+ cipher->context, src, dst, len,
iv ? iv : cipher->iv);
}
SilcBool silc_cipher_set_key(SilcCipher cipher, const unsigned char *key,
SilcUInt32 keylen, SilcBool encryption)
{
- return cipher->cipher->set_key(cipher->context, key, keylen, encryption);
+ return cipher->cipher->set_key(cipher, cipher->cipher, cipher->context,
+ (void *)key, keylen, encryption);
}
/* Sets the IV (initial vector) for the cipher. */
void silc_cipher_set_iv(SilcCipher cipher, const unsigned char *iv)
{
if (iv)
- memmove(&cipher->iv, iv, cipher->cipher->iv_len);
- cipher->cipher->set_iv(cipher->context, iv);
+ memmove(cipher->iv, iv, cipher->cipher->iv_len);
+ cipher->cipher->set_iv(cipher, cipher->cipher, cipher->context, cipher->iv);
}
/* Returns the IV (initial vector) of the cipher. */
return (const char *)cipher->cipher->name;
}
+/* Returns the algorithm name of the cipher */
+
+const char *silc_cipher_get_alg_name(SilcCipher cipher)
+{
+ return (const char *)cipher->cipher->alg_name;
+}
+
/* Returns cipher mode */
SilcCipherMode silc_cipher_get_mode(SilcCipher cipher)