-/* Internal routine to send packet */
-
-static SilcBool silc_packet_send_raw(SilcPacketStream stream,
- SilcPacketType type,
- SilcPacketFlags flags,
- SilcIdType src_id_type,
- unsigned char *src_id,
- SilcUInt32 src_id_len,
- SilcIdType dst_id_type,
- unsigned char *dst_id,
- SilcUInt32 dst_id_len,
- const unsigned char *data,
- SilcUInt32 data_len,
- SilcCipher cipher,
- SilcHmac hmac)
+/* Increments counter when encrypting in counter mode. */
+
+static inline void silc_packet_send_ctr_increment(SilcPacketStream stream,
+ SilcCipher cipher,
+ unsigned char *ret_iv)
+{
+ unsigned char *iv = silc_cipher_get_iv(cipher);
+ SilcUInt32 pc;
+
+ /* Increment packet counter */
+ SILC_GET32_MSB(pc, iv + 8);
+ pc++;
+ SILC_PUT32_MSB(pc, iv + 8);
+
+ /* Reset block counter */
+ memset(iv + 12, 0, 4);
+
+ /* If IV Included flag, return the 64-bit IV for inclusion in packet */
+ if (stream->iv_included) {
+ /* Get new nonce */
+ ret_iv[0] = silc_rng_get_byte_fast(stream->sc->engine->rng);
+ 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(pc, ret_iv + 4);
+ SILC_LOG_HEXDUMP(("IV"), ret_iv, 8);
+
+ /* Set new nonce to counter block */
+ memcpy(iv + 4, ret_iv, 4);
+ }
+
+ SILC_LOG_HEXDUMP(("Counter Block"), iv, 16);
+}
+
+/* Internal routine to assemble outgoing packet. Assembles and encryptes
+ the packet. The silc_packet_stream_write needs to be called to send it
+ after this returns TRUE. */
+
+static inline SilcBool silc_packet_send_raw(SilcPacketStream stream,
+ SilcPacketType type,
+ SilcPacketFlags flags,
+ SilcIdType src_id_type,
+ unsigned char *src_id,
+ SilcUInt32 src_id_len,
+ SilcIdType dst_id_type,
+ unsigned char *dst_id,
+ SilcUInt32 dst_id_len,
+ const unsigned char *data,
+ SilcUInt32 data_len,
+ SilcCipher cipher,
+ SilcHmac hmac)