From 32fd2624bef1d1e64b3250d7ff8475db043fd4a5 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 26 Feb 2001 17:32:07 +0000 Subject: [PATCH] updates. --- CHANGES | 23 ++++++++++++ apps/silc/clientconfig.c | 29 +++++++++------ apps/silc/testi.conf | 51 ++++++++++++++++++++++---- apps/silcd/command.c | 26 +++++++++----- apps/silcd/idlist.c | 5 ++- apps/silcd/protocol.c | 5 ++- apps/silcd/server.c | 19 +++++----- apps/silcd/serverconfig.c | 29 +++++++++------ apps/silcd/testi2.conf | 12 +++++-- doc/draft-riikonen-silc-spec-01.nroff | 33 +++++++++++------ doc/example_silc.conf | 12 +++++-- doc/example_silcd.conf | 12 +++++-- lib/silcclient/client.c | 24 +++++++------ lib/silcclient/command.c | 14 +++++--- lib/silcclient/command_reply.c | 1 + lib/silcclient/protocol.c | 5 ++- lib/silccore/silccommand.c | 10 +++--- lib/silccore/silccommand.h | 1 + lib/silccore/silcpayload.c | 2 +- lib/silccrypt/Makefile.am | 2 +- lib/silccrypt/{rijndael.c => aes.c} | 12 +++---- lib/silccrypt/{rijndael.h => aes.h} | 13 ++++--- lib/silccrypt/ciphers.h | 2 +- lib/silccrypt/silccipher.c | 52 +++++++++++++++++++-------- lib/silccrypt/silchash.c | 3 +- lib/silcsim/Makefile.am | 2 +- lib/silcske/silcske.c | 30 ++++++++-------- 27 files changed, 298 insertions(+), 131 deletions(-) rename lib/silccrypt/{rijndael.c => aes.c} (98%) rename lib/silccrypt/{rijndael.h => aes.h} (80%) diff --git a/CHANGES b/CHANGES index 9e299ecd..f970f7c9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,26 @@ +Mon Feb 26 12:13:58 EET 2001 Pekka Riikonen + + * Redefined ciphers for the SILC protocol. Added some new ciphers + and defined the key lengths for the algorithms. Changed the + code accordingly. The default key length is now 256 bits. + + * Fixed SKE key distribution function silc_ske_process_key_material + when the key length is more than 128 bits. The default key + length in SILC is now 256 bits. + + * Added new command status type: SILC_STATUS_ERR_UNKOWN_ALGORITHM + to indicate unsupported algorithm. + + * Renamed rijndael.c to aes.c and all functions as well. + + * Fixed a long standing channel key setting bug in client library. + Weird that it has never surfaced before. + + * Fixed bug in channel deletion. If the entire channel is removed + then it must also delete the references of the channel entry + from the client's channel list as the client's channel entry and + the channel's client entry share same memory. + Sun Feb 25 20:47:29 EET 2001 Pekka Riikonen * Implemented CONNECT and SHUTDOWN commands in the client. diff --git a/apps/silc/clientconfig.c b/apps/silc/clientconfig.c index 94ddb7f0..1e85aa4f 100644 --- a/apps/silc/clientconfig.c +++ b/apps/silc/clientconfig.c @@ -272,28 +272,28 @@ int silc_client_config_parse_lines(SilcClientConfig config, if (ret < 0) break; - /* Get block length */ + /* Get key length */ ret = silc_config_get_token(line, &tmp); if (ret < 0) break; if (ret == 0) { - fprintf(stderr, "%s:%d: Cipher block length not defined\n", + fprintf(stderr, "%s:%d: Cipher key length not defined\n", config->filename, pc->linenum); break; } - config->cipher->block_len = atoi(tmp); + config->cipher->key_len = atoi(tmp); silc_free(tmp); - /* Get key length */ + /* Get block length */ ret = silc_config_get_token(line, &tmp); if (ret < 0) break; if (ret == 0) { - fprintf(stderr, "%s:%d: Cipher key length not defined\n", + fprintf(stderr, "%s:%d: Cipher block length not defined\n", config->filename, pc->linenum); break; } - config->cipher->key_len = atoi(tmp); + config->cipher->block_len = atoi(tmp); silc_free(tmp); check = TRUE; @@ -554,6 +554,7 @@ void silc_client_config_register_ciphers(SilcClientConfig config) /* Load (try at least) the crypto SIM module */ SilcCipherObject cipher; SilcSimContext *sim; + char *alg_name; memset(&cipher, 0, sizeof(cipher)); cipher.name = alg->alg_name; @@ -564,25 +565,29 @@ void silc_client_config_register_ciphers(SilcClientConfig config) sim->type = SILC_SIM_CIPHER; sim->libname = alg->sim_name; + alg_name = strdup(alg->alg_name); + if (strchr(alg_name, '-')) + *strchr(alg_name, '-') = '\0'; + if ((silc_sim_load(sim))) { cipher.set_key = - silc_sim_getsym(sim, silc_sim_symname(alg->alg_name, + silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_SET_KEY)); SILC_LOG_DEBUG(("set_key=%p", cipher.set_key)); cipher.set_key_with_string = - silc_sim_getsym(sim, silc_sim_symname(alg->alg_name, + silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_SET_KEY_WITH_STRING)); SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string)); cipher.encrypt = - silc_sim_getsym(sim, silc_sim_symname(alg->alg_name, + silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_ENCRYPT_CBC)); SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt)); cipher.decrypt = - silc_sim_getsym(sim, silc_sim_symname(alg->alg_name, + silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_DECRYPT_CBC)); SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt)); cipher.context_len = - silc_sim_getsym(sim, silc_sim_symname(alg->alg_name, + silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_CONTEXT_LEN)); SILC_LOG_DEBUG(("context_len=%p", cipher.context_len)); @@ -592,6 +597,8 @@ void silc_client_config_register_ciphers(SilcClientConfig config) (app->sim_count + 1)); app->sim[app->sim_count] = sim; app->sim_count++; + + silc_free(alg_name); } else { SILC_LOG_ERROR(("Error configuring ciphers")); silc_client_stop(client); diff --git a/apps/silc/testi.conf b/apps/silc/testi.conf index 04b06230..1289ea7c 100644 --- a/apps/silc/testi.conf +++ b/apps/silc/testi.conf @@ -1,21 +1,58 @@ +# +# Configured ciphers. +# +# Format: ::: +# +# If the cipher is builtin the maybe omitted. +# [cipher] -twofish:../lib/silcsim/modules/twofish.sim.so:16:16 -rc6:../lib/silcsim/modules/rc6.sim.so:16:16 -mars:../lib/silcsim/modules/mars.sim.so:16:16 +aes-256-cbc:../lib/silcsim/modules/aes.sim.so:32:16 +aes-192-cbc:../lib/silcsim/modules/aes.sim.so:24:16 +aes-128-cbc:../lib/silcsim/modules/aes.sim.so:16:16 +twofish-256-cbc:../lib/silcsim/modules/twofish.sim.so:32:16 +twofish-192-cbc:../lib/silcsim/modules/twofish.sim.so:24:16 +twofish-128-cbc:../lib/silcsim/modules/twofish.sim.so:16:16 +mars-256-cbc:../lib/silcsim/modules/mars.sim.so:32:16 +mars-192-cbc:../lib/silcsim/modules/mars.sim.so:24:16 +mars-128-cbc:../lib/silcsim/modules/mars.sim.so:16:16 none:../lib/silcsim/modules/none.sim.so:0:0 +# +# Configured hash functions. +# +# Format: ::: +# +# If the hash function is builtin the maybe omitted. +# [hash] md5::64:16 sha1::64:20 +# +# Configured PKCS. +# +# Format: :: +# +# NOTE: must be omitted as PKCS cannot be modules currently. +# #[pkcs] #rsa::1024 #dss::1024 +# +# Configured connections to servers. +# +# Format: ::: +# +# maybe `passwd' or `pubkey'. +# [connection] -#lassi.kuo.fi.ssh.com:passwd::1333 +#lassi.kuo.fi.ssh.com:passwd::706 +# +# Commands. These are executed when SILC client is run. Normal +# SILC commands may be executed here. +# +# Format: +# [commands] -#/server lassi.kuo.fi.ssh.com -#/server lassi:1334 -#/server leevi:1333 diff --git a/apps/silcd/command.c b/apps/silcd/command.c index e09327a0..418b5b12 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -1921,7 +1921,8 @@ static void silc_server_command_join_channel(SilcServer server, SILC_PUT32_MSB(created, tmp2); tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL); keyp = silc_channel_key_payload_encode(SILC_ID_CHANNEL_LEN, tmp, - SILC_ID_CHANNEL_LEN, + strlen(channel->channel_key-> + cipher->name), channel->channel_key->cipher->name, channel->key_len / 8, channel->key); silc_free(tmp); @@ -2472,7 +2473,7 @@ SILC_SERVER_CMD_FUNC(cmode) if (mode_mask & SILC_CHANNEL_MODE_CIPHER) { if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) { /* Cipher to use protect the traffic */ - unsigned int key_len = 128; + unsigned int key_len = 256; char *cp; /* Get cipher */ @@ -2493,7 +2494,11 @@ SILC_SERVER_CMD_FUNC(cmode) /* Delete old cipher and allocate the new one */ silc_cipher_free(channel->channel_key); - silc_cipher_alloc(tmp, &channel->channel_key); + if (!silc_cipher_alloc(tmp, &channel->channel_key)) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, + SILC_STATUS_ERR_UNKNOWN_ALGORITHM); + goto out; + } key_len /= 8; if (key_len > 32) @@ -2547,9 +2552,14 @@ SILC_SERVER_CMD_FUNC(cmode) /* Delete old cipher and allocate default one */ silc_cipher_free(channel->channel_key); if (!channel->cipher) - silc_cipher_alloc("twofish", &channel->channel_key); - else - silc_cipher_alloc(channel->cipher, &channel->channel_key); + silc_cipher_alloc("aes-256-cbc", &channel->channel_key); + else { + if (!silc_cipher_alloc(channel->cipher, &channel->channel_key)) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, + SILC_STATUS_ERR_UNKNOWN_ALGORITHM); + goto out; + } + } /* Re-generate channel key */ silc_server_create_channel_key(server, channel, 0); @@ -2978,7 +2988,7 @@ SILC_SERVER_CMD_FUNC(connect) unsigned int tmp_len; unsigned int port = SILC_PORT; - SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CONNECT, cmd, 0, 0); + SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CONNECT, cmd, 1, 2); if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT) goto out; @@ -3038,7 +3048,7 @@ SILC_SERVER_CMD_FUNC(close) unsigned char *name; unsigned int port = SILC_PORT; - SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CLOSE, cmd, 0, 0); + SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CLOSE, cmd, 1, 2); if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT) goto out; diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index b4d2f7fe..d8a747fc 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -610,9 +610,12 @@ int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry) memset(entry->key, 0, entry->key_len / 8); silc_free(entry->key); } - + + /* Free all data, free also any reference from the client's channel + list since they share the same memory. */ silc_list_start(entry->user_list); while ((chl = silc_list_get(entry->user_list)) != SILC_LIST_END) { + silc_list_del(chl->client->channels, chl); silc_list_del(entry->user_list, chl); silc_free(chl); } diff --git a/apps/silcd/protocol.c b/apps/silcd/protocol.c index fdb7a38e..ecca5e68 100644 --- a/apps/silcd/protocol.c +++ b/apps/silcd/protocol.c @@ -346,6 +346,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) * End protocol */ SilcSKEKeyMaterial *keymat; + int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher, NULL); + int hash_len = ctx->ske->prop->hash->hash->hash_len; /* Send Ok to the other end if we are responder. If we are initiator we have sent this already. */ @@ -354,7 +356,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) /* Process the key material */ keymat = silc_calloc(1, sizeof(*keymat)); - silc_ske_process_key_material(ctx->ske, 16, (16 * 8), 16, keymat); + silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len, + keymat); /* Take the new keys into use. */ if (!silc_server_protocol_ke_set_keys(ctx->ske, ctx->sock, keymat, diff --git a/apps/silcd/server.c b/apps/silcd/server.c index a020fa61..89043217 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -2241,10 +2241,11 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, SILC_LOG_DEBUG(("Creating new channel")); if (!cipher) - cipher = "twofish"; + cipher = "aes-256-cbc"; /* Allocate cipher */ - silc_cipher_alloc(cipher, &key); + if (!silc_cipher_alloc(cipher, &key)) + return NULL; channel_name = strdup(channel_name); @@ -2259,7 +2260,7 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, } /* Now create the actual key material */ - silc_server_create_channel_key(server, entry, 16); + silc_server_create_channel_key(server, entry, 32); /* Notify other routers about the new channel. We send the packet to our primary route. */ @@ -2288,10 +2289,11 @@ silc_server_create_new_channel_with_id(SilcServer server, SILC_LOG_DEBUG(("Creating new channel")); if (!cipher) - cipher = "twofish"; + cipher = "aes-256-cbc"; /* Allocate cipher */ - silc_cipher_alloc(cipher, &key); + if (!silc_cipher_alloc(cipher, &key)) + return NULL; channel_name = strdup(channel_name); @@ -2305,7 +2307,7 @@ silc_server_create_new_channel_with_id(SilcServer server, } /* Now create the actual key material */ - silc_server_create_channel_key(server, entry, 16); + silc_server_create_channel_key(server, entry, 32); /* Notify other routers about the new channel. We send the packet to our primary route. */ @@ -2332,7 +2334,8 @@ void silc_server_create_channel_key(SilcServer server, unsigned int len; if (!channel->channel_key) - silc_cipher_alloc("twofish", &channel->channel_key); + if (!silc_cipher_alloc("aes-256-cbc", &channel->channel_key)) + return; if (key_len) len = key_len; @@ -2410,7 +2413,7 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, goto out; } - cipher = silc_channel_key_get_cipher(payload, NULL);; + cipher = silc_channel_key_get_cipher(payload, NULL); if (!cipher) { channel = NULL; goto out; diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index 9caff411..35e23418 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -430,28 +430,28 @@ int silc_server_config_parse_lines(SilcServerConfig config, if (ret < 0) break; - /* Get block length */ + /* Get key length */ ret = silc_config_get_token(line, &tmp); if (ret < 0) break; if (ret == 0) { - fprintf(stderr, "%s:%d: Cipher block length not defined\n", + fprintf(stderr, "%s:%d: Cipher key length not defined\n", config->filename, pc->linenum); break; } - config->cipher->block_len = atoi(tmp); + config->cipher->key_len = atoi(tmp); silc_free(tmp); - /* Get key length */ + /* Get block length */ ret = silc_config_get_token(line, &tmp); if (ret < 0) break; if (ret == 0) { - fprintf(stderr, "%s:%d: Cipher key length not defined\n", + fprintf(stderr, "%s:%d: Cipher block length not defined\n", config->filename, pc->linenum); break; } - config->cipher->key_len = atoi(tmp); + config->cipher->block_len = atoi(tmp); silc_free(tmp); check = TRUE; @@ -1192,6 +1192,7 @@ void silc_server_config_register_ciphers(SilcServerConfig config) /* Load (try at least) the crypto SIM module */ SilcCipherObject cipher; SilcSimContext *sim; + char *alg_name; memset(&cipher, 0, sizeof(cipher)); cipher.name = alg->alg_name; @@ -1202,30 +1203,36 @@ void silc_server_config_register_ciphers(SilcServerConfig config) sim->type = SILC_SIM_CIPHER; sim->libname = alg->sim_name; + alg_name = strdup(alg->alg_name); + if (strchr(alg_name, '-')) + *strchr(alg_name, '-') = '\0'; + if ((silc_sim_load(sim))) { cipher.set_key = - silc_sim_getsym(sim, silc_sim_symname(alg->alg_name, + silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_SET_KEY)); SILC_LOG_DEBUG(("set_key=%p", cipher.set_key)); cipher.set_key_with_string = - silc_sim_getsym(sim, silc_sim_symname(alg->alg_name, + silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_SET_KEY_WITH_STRING)); SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string)); cipher.encrypt = - silc_sim_getsym(sim, silc_sim_symname(alg->alg_name, + silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_ENCRYPT_CBC)); SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt)); cipher.decrypt = - silc_sim_getsym(sim, silc_sim_symname(alg->alg_name, + silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_DECRYPT_CBC)); SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt)); cipher.context_len = - silc_sim_getsym(sim, silc_sim_symname(alg->alg_name, + silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_CONTEXT_LEN)); SILC_LOG_DEBUG(("context_len=%p", cipher.context_len)); /* Put the SIM to the list of all SIM's in server */ silc_dlist_add(server->sim, sim); + + silc_free(alg_name); } else { SILC_LOG_ERROR(("Error configuring ciphers")); silc_server_stop(server); diff --git a/apps/silcd/testi2.conf b/apps/silcd/testi2.conf index 0ece9ca0..50064d06 100644 --- a/apps/silcd/testi2.conf +++ b/apps/silcd/testi2.conf @@ -1,7 +1,13 @@ [Cipher] -rc6:../lib/silcsim/modules/rc6.sim.so:16:16 -twofish:../lib/silcsim/modules/twofish.sim.so:16:16 -mars:../lib/silcsim/modules/mars.sim.so:16:16 +aes-256-cbc:../lib/silcsim/modules/aes.sim.so:32:16 +aes-192-cbc:../lib/silcsim/modules/aes.sim.so:24:16 +aes-128-cbc:../lib/silcsim/modules/aes.sim.so:16:16 +twofish-256-cbc:../lib/silcsim/modules/twofish.sim.so:32:16 +twofish-192-cbc:../lib/silcsim/modules/twofish.sim.so:24:16 +twofish-128-cbc:../lib/silcsim/modules/twofish.sim.so:16:16 +mars-256-cbc:../lib/silcsim/modules/mars.sim.so:32:16 +mars-192-cbc:../lib/silcsim/modules/mars.sim.so:24:16 +mars-128-cbc:../lib/silcsim/modules/mars.sim.so:16:16 none:../lib/silcsim/modules/none.sim.so:0:0 [HashFunction] diff --git a/doc/draft-riikonen-silc-spec-01.nroff b/doc/draft-riikonen-silc-spec-01.nroff index a2182947..85f6b101 100644 --- a/doc/draft-riikonen-silc-spec-01.nroff +++ b/doc/draft-riikonen-silc-spec-01.nroff @@ -1156,20 +1156,26 @@ must be supported in order to be compliant with this protocol. Following ciphers are defined in SILC protocol: .in 6 -aes-cbc AES in CBC mode (mandatory) -twofish-cbc Twofish in CBC mode (optional) -blowfish-cbc Blowfish in CBC mode (optional) -rc6-cbc RC6 in CBC mode (optional) -rc5-cbc RC5 in CBC mode (optional) -mars-cbc Mars in CBC mode (optional) -none No encryption (optional) +aes-256-cbc AES in CBC mode, 256 bit key (mandatory) +aes-192-cbc AES in CBC mode, 192 bit key (optional) +aes-128-cbc AES in CBC mode, 128 bit key (optional) +twofish-256-cbc Twofish in CBC mode, 256 bit key (optional) +twofish-192-cbc Twofish in CBC mode, 192 bit key (optional) +twofish-128-cbc Twofish in CBC mode, 128 bit key (optional) +blowfish-128-cbc Blowfish in CBC mode, 128 bit key (optional) +cast-256-cbc CAST-256 in CBC mode, 256 bit key (optional) +cast-192-cbc CAST-256 in CBC mode, 192 bit key (optional) +cast-128-cbc CAST-256 in CBC mode, 128 bit key (optional) +rc6-256-cbc RC6 in CBC mode, 256 bit key (optional) +rc6-192-cbc RC6 in CBC mode, 192 bit key (optional) +rc6-128-cbc RC6 in CBC mode, 128 bit key (optional) +mars-256-cbc Mars in CBC mode, 256 bit key (optional) +mars-192-cbc Mars in CBC mode, 192 bit key (optional) +mars-128-cbc Mars in CBC mode, 128 bit key (optional) +none No encryption (optional) .in 3 -All algorithms must use minimum of 128 bit key, by default. Several -algorithms, however, supports longer keys and it is recommended to use -longer keys if they are available. - Algorithm none does not perform any encryption process at all and thus is not recommended to be used. It is recommended that no client or server implementation would accept none algorithms except in special @@ -3290,6 +3296,11 @@ List of all defined command status messages following. "Authentication failed". The authentication data sent as argument were wrong and thus authentication failed. + + 46 SILC_STATUS_ERR_UNKOWN_ALGORITHM + + "The algorithm was not supported." The server does not support the + requested algorithm. .in 3 diff --git a/doc/example_silc.conf b/doc/example_silc.conf index 8dbe7ef9..abdd4284 100644 --- a/doc/example_silc.conf +++ b/doc/example_silc.conf @@ -6,9 +6,15 @@ # If the cipher is builtin the maybe omitted. # [cipher] -twofish:../lib/silcsim/modules/twofish.sim.so:16:16 -rc6:../lib/silcsim/modules/rc6.sim.so:16:16 -mars:../lib/silcsim/modules/mars.sim.so:16:16 +rijndael-256-cbc:../lib/silcsim/modules/rijndael.sim.so:32:16 +rijndael-192-cbc:../lib/silcsim/modules/rijndael.sim.so:24:16 +rijndael-128-cbc:../lib/silcsim/modules/rijndael.sim.so:16:16 +twofish-256-cbc:../lib/silcsim/modules/twofish.sim.so:32:16 +twofish-192-cbc:../lib/silcsim/modules/twofish.sim.so:24:16 +twofish-128-cbc:../lib/silcsim/modules/twofish.sim.so:16:16 +mars-256-cbc:../lib/silcsim/modules/mars.sim.so:32:16 +mars-192-cbc:../lib/silcsim/modules/mars.sim.so:24:16 +mars-128-cbc:../lib/silcsim/modules/mars.sim.so:16:16 none:../lib/silcsim/modules/none.sim.so:0:0 # diff --git a/doc/example_silcd.conf b/doc/example_silcd.conf index 53d05e1c..1aa5fc95 100644 --- a/doc/example_silcd.conf +++ b/doc/example_silcd.conf @@ -6,9 +6,15 @@ # If the cipher is builtin the maybe omitted. # [Cipher] -twofish:../lib/silcsim/modules/twofish.sim.so:16:16 -rc6:../lib/silcsim/modules/rc6.sim.so:16:16 -mars:../lib/silcsim/modules/mars.sim.so:16:16 +rijndael-256-cbc:../lib/silcsim/modules/rijndael.sim.so:32:16 +rijndael-192-cbc:../lib/silcsim/modules/rijndael.sim.so:24:16 +rijndael-128-cbc:../lib/silcsim/modules/rijndael.sim.so:16:16 +twofish-256-cbc:../lib/silcsim/modules/twofish.sim.so:32:16 +twofish-192-cbc:../lib/silcsim/modules/twofish.sim.so:24:16 +twofish-128-cbc:../lib/silcsim/modules/twofish.sim.so:16:16 +mars-256-cbc:../lib/silcsim/modules/mars.sim.so:32:16 +mars-192-cbc:../lib/silcsim/modules/mars.sim.so:24:16 +mars-128-cbc:../lib/silcsim/modules/mars.sim.so:16:16 none:../lib/silcsim/modules/none.sim.so:0:0 # diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 8447ee3c..b4f46104 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -970,6 +970,7 @@ void silc_client_packet_send_to_channel(SilcClient client, SilcCipher cipher; SilcHmac hmac; unsigned char *id_string; + unsigned int block_len; SILC_LOG_DEBUG(("Sending packet to channel")); @@ -980,14 +981,15 @@ void silc_client_packet_send_to_channel(SilcClient client, } /* Generate IV */ - if (!channel->iv) - for (i = 0; i < 16; i++) channel->iv[i] = silc_rng_get_byte(client->rng); + block_len = silc_cipher_get_block_len(channel->channel_key); + if (channel->iv[0] == '\0') + for (i = 0; i < block_len; i++) channel->iv[i] = silc_rng_get_byte(client->rng); else - silc_hash_make(client->md5hash, channel->iv, 16, channel->iv); + silc_hash_make(client->md5hash, channel->iv, block_len, channel->iv); /* Encode the channel payload */ - payload = silc_channel_payload_encode(data_len, data, 16, channel->iv, - client->rng); + payload = silc_channel_payload_encode(data_len, data, block_len, + channel->iv, client->rng); if (!payload) { client->ops->say(client, conn, "Error: Could not create packet to be sent to channel"); @@ -1031,7 +1033,7 @@ void silc_client_packet_send_to_channel(SilcClient client, /* Encrypt payload of the packet. This is encrypted with the channel key. */ channel->channel_key->cipher->encrypt(channel->channel_key->context, payload->data, payload->data, - payload->len - 16, /* -IV_LEN */ + payload->len - block_len, /* -IV_LEN */ channel->iv); /* Put the actual encrypted payload data into the buffer. */ @@ -2013,7 +2015,7 @@ void silc_client_save_channel_key(SilcClientConnection conn, /* Save the key */ key = silc_channel_key_get_key(payload, &tmp_len); cipher = silc_channel_key_get_cipher(payload, NULL); - channel->key_len = tmp_len; + channel->key_len = tmp_len * 8; channel->key = silc_calloc(tmp_len, sizeof(*channel->key)); memcpy(channel->key, key, tmp_len); @@ -2023,7 +2025,7 @@ void silc_client_save_channel_key(SilcClientConnection conn, goto out; } channel->channel_key->cipher->set_key(channel->channel_key->context, - key, tmp_len); + key, channel->key_len); /* Client is now joined to the channel */ channel->on_channel = TRUE; @@ -2066,6 +2068,7 @@ void silc_client_channel_message(SilcClient client, SilcIDCacheEntry id_cache = NULL; SilcClientID *client_id = NULL; int found = FALSE; + unsigned int block_len; /* Sanity checks */ if (packet->dst_id_type != SILC_ID_CHANNEL) @@ -2088,11 +2091,12 @@ void silc_client_channel_message(SilcClient client, /* Decrypt the channel message payload. Push the IV out of the way, since it is not encrypted (after pushing buffer->tail has the IV). */ - silc_buffer_push_tail(buffer, 16); + block_len = silc_cipher_get_block_len(channel->channel_key); + silc_buffer_push_tail(buffer, block_len); channel->channel_key->cipher->decrypt(channel->channel_key->context, buffer->data, buffer->data, buffer->len, buffer->tail); - silc_buffer_pull_tail(buffer, 16); + silc_buffer_pull_tail(buffer, block_len); /* Parse the channel message payload */ payload = silc_channel_payload_parse(buffer); diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 0afa717b..815c6caf 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -1233,6 +1233,7 @@ SILC_CLIENT_CMD_FUNC(connect) SilcClientConnection conn = cmd->conn; SilcBuffer buffer; unsigned char port[4]; + unsigned int tmp; if (!cmd->conn) { SILC_NOT_CONNECTED(cmd->client, cmd->conn); @@ -1247,8 +1248,10 @@ SILC_CLIENT_CMD_FUNC(connect) goto out; } - if (cmd->argc == 3) - SILC_PUT32_MSB(atoi(cmd->argv[2]), port); + if (cmd->argc == 3) { + tmp = atoi(cmd->argv[2]); + SILC_PUT32_MSB(tmp, port); + } if (cmd->argc == 3) buffer = silc_command_payload_encode_va(SILC_COMMAND_CONNECT, 0, 2, @@ -1282,6 +1285,7 @@ SILC_CLIENT_CMD_FUNC(close) SilcClientConnection conn = cmd->conn; SilcBuffer buffer; unsigned char port[4]; + unsigned int tmp; if (!cmd->conn) { SILC_NOT_CONNECTED(cmd->client, cmd->conn); @@ -1296,8 +1300,10 @@ SILC_CLIENT_CMD_FUNC(close) goto out; } - if (cmd->argc == 3) - SILC_PUT32_MSB(atoi(cmd->argv[2]), port); + if (cmd->argc == 3) { + tmp = atoi(cmd->argv[2]); + SILC_PUT32_MSB(tmp, port); + } if (cmd->argc == 3) buffer = silc_command_payload_encode_va(SILC_COMMAND_CLOSE, 0, 2, diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index b40426b9..468a012e 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -112,6 +112,7 @@ const SilcCommandStatusMessage silc_command_status_messages[] = { { STAT(BAD_NICKNAME), "Bad nickname" }, { STAT(BAD_CHANNEL), "Bad channel name" }, { STAT(AUTH_FAILED), "Authentication failed" }, + { STAT(UNKNOWN_ALGORITHM), "Unsupported algorithm" }, { 0, NULL } }; diff --git a/lib/silcclient/protocol.c b/lib/silcclient/protocol.c index 4444a8b3..06e0efd0 100644 --- a/lib/silcclient/protocol.c +++ b/lib/silcclient/protocol.c @@ -351,10 +351,13 @@ SILC_TASK_CALLBACK(silc_client_protocol_key_exchange) * End protocol */ SilcSKEKeyMaterial *keymat; + int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher, NULL); + int hash_len = ctx->ske->prop->hash->hash->hash_len; /* Process the key material */ keymat = silc_calloc(1, sizeof(*keymat)); - silc_ske_process_key_material(ctx->ske, 16, (16 * 8), 16, keymat); + silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len, + keymat); /* Take the negotiated keys into use. */ silc_client_protocol_ke_set_keys(ctx->ske, ctx->sock, keymat, diff --git a/lib/silccore/silccommand.c b/lib/silccore/silccommand.c index 1c16ac6c..3185fe30 100644 --- a/lib/silccore/silccommand.c +++ b/lib/silccore/silccommand.c @@ -76,10 +76,12 @@ SilcCommandPayload silc_command_payload_parse(SilcBuffer buffer) } silc_buffer_pull(buffer, SILC_COMMAND_PAYLOAD_LEN); - new->args = silc_argument_payload_parse(buffer, args_num); - if (!new->args) { - silc_free(new); - return NULL; + if (args_num) { + new->args = silc_argument_payload_parse(buffer, args_num); + if (!new->args) { + silc_free(new); + return NULL; + } } silc_buffer_push(buffer, SILC_COMMAND_PAYLOAD_LEN); diff --git a/lib/silccore/silccommand.h b/lib/silccore/silccommand.h index 4f29464c..ec34d834 100644 --- a/lib/silccore/silccommand.h +++ b/lib/silccore/silccommand.h @@ -128,6 +128,7 @@ typedef unsigned short SilcCommandStatus; #define SILC_STATUS_ERR_BAD_NICKNAME 43 #define SILC_STATUS_ERR_BAD_CHANNEL 44 #define SILC_STATUS_ERR_AUTH_FAILED 45 +#define SILC_STATUS_ERR_UNKNOWN_ALGORITHM 46 /* Prototypes */ SilcCommandPayload silc_command_payload_parse(SilcBuffer buffer); diff --git a/lib/silccore/silcpayload.c b/lib/silccore/silcpayload.c index d5392169..57e49ad8 100644 --- a/lib/silccore/silcpayload.c +++ b/lib/silccore/silcpayload.c @@ -403,7 +403,7 @@ void silc_argument_payload_free(SilcArgumentPayload payload) unsigned int silc_argument_get_arg_num(SilcArgumentPayload payload) { - return payload->argc; + return payload ? payload->argc : 0; } /* Returns first argument from payload. */ diff --git a/lib/silccrypt/Makefile.am b/lib/silccrypt/Makefile.am index 66a9fbe0..933f5e16 100644 --- a/lib/silccrypt/Makefile.am +++ b/lib/silccrypt/Makefile.am @@ -27,7 +27,7 @@ libsilccrypt_a_SOURCES = \ rc6.c \ mars.c \ md5.c \ - rijndael.c \ + aes.c \ rsa.c \ sha1.c \ twofish.c \ diff --git a/lib/silccrypt/rijndael.c b/lib/silccrypt/aes.c similarity index 98% rename from lib/silccrypt/rijndael.c rename to lib/silccrypt/aes.c index 1f7cadad..9956c1ee 100644 --- a/lib/silccrypt/rijndael.c +++ b/lib/silccrypt/aes.c @@ -40,7 +40,7 @@ Mean: 500 cycles = 51.2 mbits/sec */ #include "silcincludes.h" -#include "rijndael.h" +#include "aes.h" /* * SILC Crypto API for Rijndael @@ -48,7 +48,7 @@ Mean: 500 cycles = 51.2 mbits/sec /* Sets the key for the cipher. */ -SILC_CIPHER_API_SET_KEY(rijndael) +SILC_CIPHER_API_SET_KEY(aes) { rijndael_set_key((RijndaelContext *)context, (unsigned int *)key, keylen); return 1; @@ -57,7 +57,7 @@ SILC_CIPHER_API_SET_KEY(rijndael) /* Sets the string as a new key for the cipher. The string is first hashed and then used as a new key. */ -SILC_CIPHER_API_SET_KEY_WITH_STRING(rijndael) +SILC_CIPHER_API_SET_KEY_WITH_STRING(aes) { /* unsigned char key[md5_hash_len]; SilcMarsContext *ctx = (SilcMarsContext *)context; @@ -72,7 +72,7 @@ SILC_CIPHER_API_SET_KEY_WITH_STRING(rijndael) /* Returns the size of the cipher context. */ -SILC_CIPHER_API_CONTEXT_LEN(rijndael) +SILC_CIPHER_API_CONTEXT_LEN(aes) { return sizeof(RijndaelContext); } @@ -80,7 +80,7 @@ SILC_CIPHER_API_CONTEXT_LEN(rijndael) /* Encrypts with the cipher in CBC mode. Source and destination buffers maybe one and same. */ -SILC_CIPHER_API_ENCRYPT_CBC(rijndael) +SILC_CIPHER_API_ENCRYPT_CBC(aes) { unsigned int *in, *out, *tiv; unsigned int tmp[4]; @@ -119,7 +119,7 @@ SILC_CIPHER_API_ENCRYPT_CBC(rijndael) /* Decrypts with the cipher in CBC mode. Source and destination buffers maybe one and same. */ -SILC_CIPHER_API_DECRYPT_CBC(rijndael) +SILC_CIPHER_API_DECRYPT_CBC(aes) { unsigned int *tiv, *in, *out; unsigned int tmp[4], tmp2[4]; diff --git a/lib/silccrypt/rijndael.h b/lib/silccrypt/aes.h similarity index 80% rename from lib/silccrypt/rijndael.h rename to lib/silccrypt/aes.h index 15fc3c8f..97d684d2 100644 --- a/lib/silccrypt/rijndael.h +++ b/lib/silccrypt/aes.h @@ -20,6 +20,9 @@ /* * $Id$ * $Log$ + * Revision 1.1 2001/02/26 17:32:08 priikone + * updates. + * * Revision 1.2 2000/10/02 18:31:46 priikone * Added rijndael (AES) to cipher list. * @@ -38,11 +41,11 @@ * SILC Crypto API for Rijndael */ -SILC_CIPHER_API_SET_KEY(rijndael); -SILC_CIPHER_API_SET_KEY_WITH_STRING(rijndael); -SILC_CIPHER_API_CONTEXT_LEN(rijndael); -SILC_CIPHER_API_ENCRYPT_CBC(rijndael); -SILC_CIPHER_API_DECRYPT_CBC(rijndael); +SILC_CIPHER_API_SET_KEY(aes); +SILC_CIPHER_API_SET_KEY_WITH_STRING(aes); +SILC_CIPHER_API_CONTEXT_LEN(aes); +SILC_CIPHER_API_ENCRYPT_CBC(aes); +SILC_CIPHER_API_DECRYPT_CBC(aes); #endif diff --git a/lib/silccrypt/ciphers.h b/lib/silccrypt/ciphers.h index b7f83fc7..e13aa5f7 100644 --- a/lib/silccrypt/ciphers.h +++ b/lib/silccrypt/ciphers.h @@ -25,6 +25,6 @@ #include "mars.h" #include "rc6.h" #include "twofish.h" -#include "rijndael.h" +#include "aes.h" #endif diff --git a/lib/silccrypt/silccipher.c b/lib/silccrypt/silccipher.c index 824bcbe2..0c8b6c77 100644 --- a/lib/silccrypt/silccipher.c +++ b/lib/silccrypt/silccipher.c @@ -34,22 +34,47 @@ struct SilcCipherListStruct { /* Dynamically registered list of ciphers. */ struct SilcCipherListStruct *silc_cipher_list = NULL; -/* XXX: add the other good ciphers here as well */ - /* Staticly declared list of ciphers. This is used if system doesn't support SIM's. */ SilcCipherObject silc_cipher_builtin_list[] = { - { "twofish", 16, 16, silc_twofish_set_key, silc_twofish_set_key_with_string, + { "aes-256-cbc", 16, 256, silc_aes_set_key, + silc_aes_set_key_with_string, silc_aes_encrypt_cbc, + silc_aes_decrypt_cbc, silc_aes_context_len }, + { "aes-192-cbc", 16, 192, silc_aes_set_key, + silc_aes_set_key_with_string, silc_aes_encrypt_cbc, + silc_aes_decrypt_cbc, silc_aes_context_len }, + { "aes-128-cbc", 16, 128, silc_aes_set_key, + silc_aes_set_key_with_string, silc_aes_encrypt_cbc, + silc_aes_decrypt_cbc, silc_aes_context_len }, + { "twofish-256-cbc", 16, 256, silc_twofish_set_key, + silc_twofish_set_key_with_string, + silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc, + silc_twofish_context_len }, + { "twofish-192-cbc", 16, 192, silc_twofish_set_key, + silc_twofish_set_key_with_string, + silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc, + silc_twofish_context_len }, + { "twofish-128-cbc", 16, 128, silc_twofish_set_key, + silc_twofish_set_key_with_string, silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc, silc_twofish_context_len }, - { "aes", 16, 16, silc_rijndael_set_key, - silc_rijndael_set_key_with_string, silc_rijndael_encrypt_cbc, - silc_rijndael_decrypt_cbc, silc_rijndael_context_len }, - { "rc6", 16, 16, silc_rc6_set_key, silc_rc6_set_key_with_string, + { "rc6-256-cbc", 16, 256, silc_rc6_set_key, silc_rc6_set_key_with_string, + silc_rc6_encrypt_cbc, silc_rc6_decrypt_cbc, + silc_rc6_context_len }, + { "rc6-192-cbc", 16, 192, silc_rc6_set_key, silc_rc6_set_key_with_string, + silc_rc6_encrypt_cbc, silc_rc6_decrypt_cbc, + silc_rc6_context_len }, + { "rc6-128-cbc", 16, 128, silc_rc6_set_key, silc_rc6_set_key_with_string, silc_rc6_encrypt_cbc, silc_rc6_decrypt_cbc, silc_rc6_context_len }, - { "mars", 16, 16, silc_mars_set_key, silc_mars_set_key_with_string, + { "mars-256-cbc", 16, 256, silc_mars_set_key, silc_mars_set_key_with_string, + silc_mars_encrypt_cbc, silc_mars_decrypt_cbc, + silc_mars_context_len }, + { "mars-192-cbc", 16, 192, silc_mars_set_key, silc_mars_set_key_with_string, + silc_mars_encrypt_cbc, silc_mars_decrypt_cbc, + silc_mars_context_len }, + { "mars-128-cbc", 16, 128, silc_mars_set_key, silc_mars_set_key_with_string, silc_mars_encrypt_cbc, silc_mars_decrypt_cbc, silc_mars_context_len }, { "none", 0, 0, silc_none_set_key, silc_none_set_key_with_string, @@ -175,7 +200,7 @@ int silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher) c = c->next; } - if (!c) + if (!c || !c->cipher->context_len) goto check_builtin; /* Set the pointers */ @@ -197,6 +222,7 @@ int silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher) if (silc_cipher_builtin_list[i].name == NULL) { silc_free(*new_cipher); + *new_cipher = NULL; return FALSE; } @@ -305,20 +331,16 @@ void silc_cipher_get_iv(SilcCipher itself, unsigned char *iv) } /* Returns the key length of the cipher. */ -/* XXX */ unsigned int silc_cipher_get_key_len(SilcCipher itself, const unsigned char *name) { - - return TRUE; + return itself->cipher->key_len; } /* Returns the block size of the cipher. */ -/* XXX */ unsigned int silc_cipher_get_block_len(SilcCipher itself) { - - return TRUE; + return itself->cipher->block_len; } diff --git a/lib/silccrypt/silchash.c b/lib/silccrypt/silchash.c index 8bb73393..58cecec9 100644 --- a/lib/silccrypt/silchash.c +++ b/lib/silccrypt/silchash.c @@ -156,7 +156,7 @@ int silc_hash_alloc(const unsigned char *name, SilcHash *new_hash) h = h->next; } - if (!h) + if (!h || !h->hash->context_len) goto check_builtin; /* Set the pointers */ @@ -174,6 +174,7 @@ int silc_hash_alloc(const unsigned char *name, SilcHash *new_hash) if (silc_hash_builtin_list[i].name == NULL) { silc_free(*new_hash); + *new_hash = NULL; return FALSE; } diff --git a/lib/silcsim/Makefile.am b/lib/silcsim/Makefile.am index 3d761a4d..527b5056 100644 --- a/lib/silcsim/Makefile.am +++ b/lib/silcsim/Makefile.am @@ -39,7 +39,7 @@ SIM_CIPHER_OBJS = \ rc5.o \ rc6.o \ mars.o \ - rijndael.o \ + aes.o \ rsa.o \ twofish.o diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index 7a7f6b69..e06dab55 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -1265,30 +1265,31 @@ SilcSKEStatus silc_ske_process_key_material(SilcSKE ske, if (enc_key_len > (3 * hash_len)) return SILC_SKE_STATUS_ERROR; + /* Take first round */ memset(k1, 0, sizeof(k1)); silc_hash_make(ske->prop->hash, buf->data, buf->len, k1); - /* XXX */ - dist = silc_buffer_alloc(hash_len * 3); - - silc_buffer_pull_tail(dist, klen + hash_len); + /* Take second round */ + dist = silc_buffer_alloc(klen + hash_len); + silc_buffer_pull_tail(dist, SILC_BUFFER_END(dist)); silc_buffer_format(dist, SILC_STR_UI_XNSTRING(tmpbuf, klen), SILC_STR_UI_XNSTRING(k1, hash_len), SILC_STR_END); - memset(k2, 0, sizeof(k2)); silc_hash_make(ske->prop->hash, dist->data, dist->len, k2); + /* Take third round */ + dist = silc_buffer_realloc(dist, klen + hash_len + hash_len); silc_buffer_pull(dist, klen + hash_len); silc_buffer_format(dist, SILC_STR_UI_XNSTRING(k2, hash_len), SILC_STR_END); silc_buffer_push(dist, klen + hash_len); - memset(k3, 0, sizeof(k3)); silc_hash_make(ske->prop->hash, dist->data, dist->len, k3); - + + /* Then, save the keys */ dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char)); memcpy(dtmp, k1, hash_len); memcpy(dtmp + hash_len, k2, hash_len); @@ -1323,30 +1324,31 @@ SilcSKEStatus silc_ske_process_key_material(SilcSKE ske, if (enc_key_len > (3 * hash_len)) return SILC_SKE_STATUS_ERROR; + /* Take first round */ memset(k1, 0, sizeof(k1)); silc_hash_make(ske->prop->hash, buf->data, buf->len, k1); - /* XXX */ - dist = silc_buffer_alloc(hash_len * 3); - - silc_buffer_pull_tail(dist, klen + hash_len); + /* Take second round */ + dist = silc_buffer_alloc(klen + hash_len); + silc_buffer_pull_tail(dist, SILC_BUFFER_END(dist)); silc_buffer_format(dist, SILC_STR_UI_XNSTRING(tmpbuf, klen), SILC_STR_UI_XNSTRING(k1, hash_len), SILC_STR_END); - memset(k2, 0, sizeof(k2)); silc_hash_make(ske->prop->hash, dist->data, dist->len, k2); + /* Take third round */ + dist = silc_buffer_realloc(dist, klen + hash_len + hash_len); silc_buffer_pull(dist, klen + hash_len); silc_buffer_format(dist, SILC_STR_UI_XNSTRING(k2, hash_len), SILC_STR_END); silc_buffer_push(dist, klen + hash_len); - memset(k3, 0, sizeof(k3)); silc_hash_make(ske->prop->hash, dist->data, dist->len, k3); - + + /* Then, save the keys */ dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char)); memcpy(dtmp, k1, hash_len); memcpy(dtmp + hash_len, k2, hash_len); -- 2.24.0