+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.
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;
/* 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;
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));
(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);
+#
+# 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
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);
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 */
/* 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)
/* 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);
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;
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;
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);
}
* 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. */
/* 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,
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);
}
/* 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. */
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);
}
/* 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. */
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;
goto out;
}
- cipher = silc_channel_key_get_cipher(payload, NULL);;
+ cipher = silc_channel_key_get_cipher(payload, NULL);
if (!cipher) {
channel = NULL;
goto out;
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;
/* 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;
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);
[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]
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
"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
# 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
#
# 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
#
SilcCipher cipher;
SilcHmac hmac;
unsigned char *id_string;
+ unsigned int block_len;
SILC_LOG_DEBUG(("Sending packet to channel"));
}
/* 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");
/* 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. */
/* 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);
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;
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)
/* 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);
SilcClientConnection conn = cmd->conn;
SilcBuffer buffer;
unsigned char port[4];
+ unsigned int tmp;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
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,
SilcClientConnection conn = cmd->conn;
SilcBuffer buffer;
unsigned char port[4];
+ unsigned int tmp;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
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,
{ STAT(BAD_NICKNAME), "Bad nickname" },
{ STAT(BAD_CHANNEL), "Bad channel name" },
{ STAT(AUTH_FAILED), "Authentication failed" },
+ { STAT(UNKNOWN_ALGORITHM), "Unsupported algorithm" },
{ 0, NULL }
};
* 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,
}
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);
#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);
unsigned int silc_argument_get_arg_num(SilcArgumentPayload payload)
{
- return payload->argc;
+ return payload ? payload->argc : 0;
}
/* Returns first argument from payload. */
rc6.c \
mars.c \
md5.c \
- rijndael.c \
+ aes.c \
rsa.c \
sha1.c \
twofish.c \
*/
#include "silcincludes.h"
-#include "rijndael.h"
+#include "aes.h"
/*
* SILC Crypto API for Rijndael
/* 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;
/* 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;
/* Returns the size of the cipher context. */
-SILC_CIPHER_API_CONTEXT_LEN(rijndael)
+SILC_CIPHER_API_CONTEXT_LEN(aes)
{
return sizeof(RijndaelContext);
}
/* 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];
/* 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];
/*
* $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
#include "mars.h"
#include "rc6.h"
#include "twofish.h"
-#include "rijndael.h"
+#include "aes.h"
#endif
/* 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,
c = c->next;
}
- if (!c)
+ if (!c || !c->cipher->context_len)
goto check_builtin;
/* Set the pointers */
if (silc_cipher_builtin_list[i].name == NULL) {
silc_free(*new_cipher);
+ *new_cipher = NULL;
return FALSE;
}
}
/* 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;
}
h = h->next;
}
- if (!h)
+ if (!h || !h->hash->context_len)
goto check_builtin;
/* Set the pointers */
if (silc_hash_builtin_list[i].name == NULL) {
silc_free(*new_hash);
+ *new_hash = NULL;
return FALSE;
}
rc5.o \
rc6.o \
mars.o \
- rijndael.o \
+ aes.o \
rsa.o \
twofish.o
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);
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);