updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 26 Feb 2001 17:32:07 +0000 (17:32 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 26 Feb 2001 17:32:07 +0000 (17:32 +0000)
27 files changed:
CHANGES
apps/silc/clientconfig.c
apps/silc/testi.conf
apps/silcd/command.c
apps/silcd/idlist.c
apps/silcd/protocol.c
apps/silcd/server.c
apps/silcd/serverconfig.c
apps/silcd/testi2.conf
doc/draft-riikonen-silc-spec-01.nroff
doc/example_silc.conf
doc/example_silcd.conf
lib/silcclient/client.c
lib/silcclient/command.c
lib/silcclient/command_reply.c
lib/silcclient/protocol.c
lib/silccore/silccommand.c
lib/silccore/silccommand.h
lib/silccore/silcpayload.c
lib/silccrypt/Makefile.am
lib/silccrypt/aes.c [moved from lib/silccrypt/rijndael.c with 98% similarity]
lib/silccrypt/aes.h [moved from lib/silccrypt/rijndael.h with 80% similarity]
lib/silccrypt/ciphers.h
lib/silccrypt/silccipher.c
lib/silccrypt/silchash.c
lib/silcsim/Makefile.am
lib/silcske/silcske.c

diff --git a/CHANGES b/CHANGES
index 9e299ecdd69ec7e15d5b713e6319579077661192..f970f7c93c6aa60fc8a2a537e5847d44235df85e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,26 @@
+Mon Feb 26 12:13:58 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * 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 <priikone@poseidon.pspt.fi>
 
        * Implemented CONNECT and SHUTDOWN commands in the client.
index 94ddb7f04943f2e1e5c864ba8c9d09f04c4f69af..1e85aa4f2150e490f7a8604d1a331f86ca7307c5 100644 (file)
@@ -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);
index 04b0623038947558b423ea52c7112e2b9319a964..1289ea7c05424b72009b53a34c656f8586a1539c 100644 (file)
@@ -1,21 +1,58 @@
+#
+# Configured ciphers.
+#
+# Format: <name>:<module path>:<key length>:<block length>
+#
+# If the cipher is builtin the <module path> 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: <name>:<module path>:<block length>:<digest length>
+#
+# If the hash function is builtin the <module path> maybe omitted.
+#
 [hash]
 md5::64:16
 sha1::64:20
 
+#
+# Configured PKCS.
+#
+# Format: <name>:<module path>:<key length>
+#
+# NOTE: <module path> must be omitted as PKCS cannot be modules currently.
+#
 #[pkcs]
 #rsa::1024
 #dss::1024
 
+#
+# Configured connections to servers.
+#
+# Format: <remote host>:<auth type>:<auth data>:<port>
+#
+# <auth type> 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: <command>
+#
 [commands]
-#/server lassi.kuo.fi.ssh.com
-#/server lassi:1334
-#/server leevi:1333
index e09327a0b0a100d80286a2631d72165915db669f..418b5b12f72f199aa143eed8ee90de6b86603b0d 100644 (file)
@@ -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;
index b4d2f7fe43be50a5f78f965c050c2699f38d2ffc..d8a747fcacd85cd140b87935f223aa62fa1c1027 100644 (file)
@@ -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);
     }
index fdb7a38e8c66679697024af832fa4a86ada7bb7a..ecca5e688776ec5ea88428671ba5056370218227 100644 (file)
@@ -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,
index a020fa61bd6cf3354f8cd8de4787567b1a279334..89043217a744ddfe7036f0caf3d003477eeb239a 100644 (file)
@@ -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;
index 9caff411cf604a9d4d2fd7918a0c221a32f8c783..35e234183a09558a4979f329ef7b937368c6bc16 100644 (file)
@@ -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);
index 0ece9ca0eb15e69e1ae9da619e89e219cc856ee0..50064d06d312213d69701d4b9a19f14103d3e2f4 100644 (file)
@@ -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]
index a2182947048fa82ade3dbc5d5ee0ba3c3a59d1a4..85f6b1012cf83c0884be4e007d9dcfebcfa42c13 100644 (file)
@@ -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
 
 
index 8dbe7ef97d0f005500431d46fee0b68cf349e386..abdd4284b1a0639a0f7ad0dd14fde71f38489dc8 100644 (file)
@@ -6,9 +6,15 @@
 # If the cipher is builtin the <module path> 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
 
 #
index 53d05e1c5d51bb20a15a858208af546a213e8b2e..1aa5fc957d1f26d442caeda6beb19a9eae23343f 100644 (file)
@@ -6,9 +6,15 @@
 # If the cipher is builtin the <module path> 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
 
 #
index 8447ee3cc4ab91f0394ab67b1a720efa772641dd..b4f46104e8e13cac0048d511aac65aa3c5cb469b 100644 (file)
@@ -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);
index 0afa717bb2974a95b1796c2586bbac6c6de3eb19..815c6cafabd86756b25b2aaacafe0ce0bc9a88c0 100644 (file)
@@ -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, 
index b40426b9c76f6b4adaba2d8e1d50c11fc91cdf5f..468a012ea2fafef672b37e3e639a62305daa3231 100644 (file)
@@ -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 }
 };
index 4444a8b31df389d27d28f6e8ac60831f70b990d7..06e0efd08f59b82b8e41110cc0d1d585afdace17 100644 (file)
@@ -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,
index 1c16ac6c61ea915ef91988b84e9f55c7926e6aa3..3185fe305cb064810752a2e2d6ea7b5e54206f37 100644 (file)
@@ -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);
 
index 4f29464c3a8a5e2143b7df781cf40671d7a74c55..ec34d8344b2cfa3c95abae57e70b27bfc50f8a40 100644 (file)
@@ -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);
index d53921698cbba75f7daa7e7b79006774816db243..57e49ad875b0f6a4501e2d118901fa31169fa7af 100644 (file)
@@ -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. */
index 66a9fbe080e12843ae96b1ed3cf3c9fcf718c6a5..933f5e163cca4a93ed4c0ea3d4febef13479a4be 100644 (file)
@@ -27,7 +27,7 @@ libsilccrypt_a_SOURCES = \
        rc6.c \
        mars.c \
        md5.c \
-       rijndael.c \
+       aes.c \
        rsa.c \
        sha1.c \
        twofish.c \
similarity index 98%
rename from lib/silccrypt/rijndael.c
rename to lib/silccrypt/aes.c
index 1f7cadadcd13f3320bc627190b472bc9f2433b58..9956c1ee59730a20e15111a97abadd3e63fc79ff 100644 (file)
@@ -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];
similarity index 80%
rename from lib/silccrypt/rijndael.h
rename to lib/silccrypt/aes.h
index 15fc3c8f8a9a30f4aa0407877692ef66dbd4571b..97d684d2c0817f247cbae4d1205237731c20ab07 100644 (file)
@@ -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.
  *
  * 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
index b7f83fc76253bebf9c37402d3eb929ee07b0192d..e13aa5f70b40ca6ce34f936b2a89599143ea9f45 100644 (file)
@@ -25,6 +25,6 @@
 #include "mars.h"
 #include "rc6.h"
 #include "twofish.h"
-#include "rijndael.h"
+#include "aes.h"
 
 #endif
index 824bcbe21fa081e4b0f868b9895d2835efc7e3b0..0c8b6c77b18a5197aba5daaf228747917ae6720f 100644 (file)
@@ -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;
 }
index 8bb7339336e98188d45ec00925a4c02b0527d3f5..58cecec9cb44225d0b0f2b450fe1ebb8dc6db15e 100644 (file)
@@ -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;
   }
   
index 3d761a4d76b8418c7c83573fb2e5bb3a8b132563..527b50564acf7ba5e93e0e045cc609107b66cda5 100644 (file)
@@ -39,7 +39,7 @@ SIM_CIPHER_OBJS = \
         rc5.o \
         rc6.o \
         mars.o \
-        rijndael.o \
+        aes.o \
         rsa.o \
         twofish.o
 
index 7a7f6b6983a5fcdb2e673e8580da9d3ab71908b0..e06dab55e17eb029167663ce39d112383a8ddfdb 100644 (file)
@@ -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);