From: Pekka Riikonen Date: Mon, 5 Nov 2007 20:34:55 +0000 (+0000) Subject: Fixed CTR rekey. Rewrote IV Included CTR mode encryption/decryption X-Git-Tag: silc.toolkit.1.1.4 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=b5c781b1cd1c64039084ad29e2eed2b95a5cedb8 Fixed CTR rekey. Rewrote IV Included CTR mode encryption/decryption in packet engine. --- diff --git a/CHANGES b/CHANGES index 95824e06..7a495d43 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +Mon Nov 5 22:24:25 EET 2007 Pekka Riikonen + + * Fixed CTR mode rekey. Affected file is lib/silcske/silcske.c. + + * Rewrote the IV Included CTR mode encryption/decryption in + packet engine. Affected file is lib/silccore/silcpacket.c. + Sun Nov 4 15:20:25 EET 2007 Pekka Riikonen * Removed module_path and module options from the server diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index d03f0d85..bea63579 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -1471,14 +1471,6 @@ static inline void silc_packet_send_ctr_increment(SilcPacketStream stream, unsigned char *iv = silc_cipher_get_iv(cipher); SilcUInt32 pc1, pc2; - /* Increment 64-bit packet counter */ - SILC_GET32_MSB(pc1, iv + 4); - SILC_GET32_MSB(pc2, iv + 8); - if (++pc2 == 0) - ++pc1; - SILC_PUT32_MSB(pc1, iv + 4); - SILC_PUT32_MSB(pc2, iv + 8); - /* Reset block counter */ memset(iv + 12, 0, 4); @@ -1489,11 +1481,24 @@ static inline void silc_packet_send_ctr_increment(SilcPacketStream stream, ret_iv[1] = ret_iv[0] + iv[4]; ret_iv[2] = ret_iv[0] ^ ret_iv[1]; ret_iv[3] = ret_iv[0] + ret_iv[2]; - SILC_PUT32_MSB(pc2, ret_iv + 4); + + /* Increment 32-bit packet counter */ + SILC_GET32_MSB(pc1, iv + 8); + pc1++; + SILC_PUT32_MSB(pc1, ret_iv + 4); + SILC_LOG_HEXDUMP(("IV"), ret_iv, 8); /* Set new nonce to counter block */ - memcpy(iv + 4, ret_iv, 4); + memcpy(iv + 4, ret_iv, 8); + } else { + /* Increment 64-bit packet counter */ + SILC_GET32_MSB(pc1, iv + 4); + SILC_GET32_MSB(pc2, iv + 8); + if (++pc2 == 0) + ++pc1; + SILC_PUT32_MSB(pc1, iv + 4); + SILC_PUT32_MSB(pc2, iv + 8); } SILC_LOG_HEXDUMP(("Counter Block"), iv, 16); diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index 4db20986..4a407490 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -3312,6 +3312,12 @@ SilcBool silc_ske_set_keys(SilcSKE ske, return FALSE; } + /* Allocate hash */ + if (ret_hash) { + if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash)) + return FALSE; + } + /* Set key material */ memset(iv, 0, sizeof(iv)); if (ske->responder) { @@ -3320,10 +3326,22 @@ SilcBool silc_ske_set_keys(SilcSKE ske, keymat->enc_key_len, TRUE); if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) { - memcpy(iv, ske->hash, 4); - memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8); + /* Counter mode */ + if (!ske->rekeying) { + /* Set IV. */ + memcpy(iv, ske->hash, 4); + if (!iv_included) + memcpy(iv + 4, keymat->receive_iv, 8); + } else { + /* Rekey, recompute the truncated hash value. */ + silc_hash_make(prop->hash, keymat->receive_iv, 8, iv); + if (!iv_included) + memcpy(iv + 4, keymat->receive_iv, 8); + } + silc_cipher_set_iv(*ret_send_key, iv); } else { + /* Other modes */ silc_cipher_set_iv(*ret_send_key, keymat->receive_iv); } } @@ -3332,10 +3350,22 @@ SilcBool silc_ske_set_keys(SilcSKE ske, keymat->enc_key_len, FALSE); if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) { - memcpy(iv, ske->hash, 4); - memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8); + /* Counter mode */ + if (!ske->rekeying) { + /* Set IV. */ + memcpy(iv, ske->hash, 4); + if (!iv_included) + memcpy(iv + 4, keymat->send_iv, 8); + } else { + /* Rekey, recompute the truncated hash value. */ + silc_hash_make(prop->hash, keymat->send_iv, 8, iv); + if (!iv_included) + memcpy(iv + 4, keymat->send_iv, 8); + } + silc_cipher_set_iv(*ret_receive_key, iv); } else { + /* Other modes */ silc_cipher_set_iv(*ret_receive_key, keymat->send_iv); } } @@ -3351,10 +3381,22 @@ SilcBool silc_ske_set_keys(SilcSKE ske, keymat->enc_key_len, TRUE); if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) { - memcpy(iv, ske->hash, 4); - memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8); + /* Counter mode */ + if (!ske->rekeying) { + /* Set IV. */ + memcpy(iv, ske->hash, 4); + if (!iv_included) + memcpy(iv + 4, keymat->send_iv, 8); + } else { + /* Rekey, recompute the truncated hash value. */ + silc_hash_make(prop->hash, keymat->send_iv, 8, iv); + if (!iv_included) + memcpy(iv + 4, keymat->send_iv, 8); + } + silc_cipher_set_iv(*ret_send_key, iv); } else { + /* Other modes */ silc_cipher_set_iv(*ret_send_key, keymat->send_iv); } } @@ -3363,10 +3405,23 @@ SilcBool silc_ske_set_keys(SilcSKE ske, keymat->enc_key_len, FALSE); if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) { - memcpy(iv, ske->hash, 4); - memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8); + /* Counter mode */ + if (!ske->rekeying) { + /* Set IV. If IV Included flag was negotiated we only set the + truncated hash value. */ + memcpy(iv, ske->hash, 4); + if (!iv_included) + memcpy(iv + 4, keymat->receive_iv, 8); + } else { + /* Rekey, recompute the truncated hash value. */ + silc_hash_make(prop->hash, keymat->receive_iv, 8, iv); + if (!iv_included) + memcpy(iv + 4, keymat->receive_iv, 8); + } + silc_cipher_set_iv(*ret_receive_key, iv); } else { + /* Other modes */ silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv); } } @@ -3378,12 +3433,6 @@ SilcBool silc_ske_set_keys(SilcSKE ske, keymat->hmac_key_len); } - /* Allocate hash */ - if (ret_hash) { - if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash)) - return FALSE; - } - return TRUE; }