Fixed decryption length calculation to use multiple by blocksize
authorPekka Riikonen <priikone@silcnet.org>
Wed, 4 Dec 2002 16:30:17 +0000 (16:30 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 4 Dec 2002 16:30:17 +0000 (16:30 +0000)
length.

CHANGES
lib/silccore/silcmessage.c

diff --git a/CHANGES b/CHANGES
index 66528327131b0295cf5f55a4ecf10e96cf18f30d..8c3121770ef4d289f55c365a6f7e501c87586a8d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+Wed Dec  4 18:29:13 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Calculate the correct length for signed messages before
+         encrypting, it must be multiple by block size.  Affected
+         file lib/silccore/silcmessage.c.
+
 Tue Dec  3 23:26:55 EET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Fixed founder key sending in CMODE command in client.
index 66bd1b9849f8999b2f7c959445d55b6f6971335c..fa9181c3d101780383c152a383ba9b252aae4ebe 100644 (file)
@@ -67,8 +67,8 @@ bool silc_message_payload_decrypt(unsigned char *data,
                                  SilcHmac hmac,
                                  bool check_mac)
 {
-  SilcUInt32 mac_len, iv_len = 0;
-  SilcUInt16 len, totlen;
+  SilcUInt32 mac_len, iv_len = 0, block_len;
+  SilcUInt16 len, totlen, dlen;
   unsigned char mac[32], *ivp, *dec;
   
   mac_len = silc_hmac_len(hmac);
@@ -94,17 +94,26 @@ bool silc_message_payload_decrypt(unsigned char *data,
     SILC_LOG_DEBUG(("MAC is Ok"));
   }
 
+  /* Decrypt the entire buffer into allocated decryption buffer, since we
+     do not reliably know its encrypted length (it may include unencrypted
+     data at the end). */
+
   /* Get pointer to the IV */
   ivp = (iv_len ? data + (data_len - iv_len - mac_len) :
         silc_cipher_get_iv(cipher));
 
-  /* Decrypt the entire buffer into allocated decryption buffer.  Then
-     use only the Message Payload and don't touch data after that, since
-     it may not be even encrypted (it may include signature payload).
-     Since we do not reliably know how long the Message Payload is we 
-     decrypt entire data buffer. */
-  dec = silc_malloc(data_len - iv_len - mac_len);
-  silc_cipher_decrypt(cipher, data, dec, data_len - iv_len - mac_len, ivp);
+  /* Allocate buffer for decryption.  Since there might be unencrypted
+     data at the end, it might not be multiple by block size, make it so. */
+  block_len = silc_cipher_get_block_len(cipher);
+  dlen = data_len - iv_len - mac_len;
+  if (dlen & (block_len - 1))
+    dlen += SILC_MESSAGE_PAD(dlen);
+  if (dlen > data_len - iv_len - mac_len)
+    dlen -= block_len;
+  dec = silc_malloc(dlen);
+
+  /* Decrypt */
+  silc_cipher_decrypt(cipher, data, dec, dlen, ivp);
 
   /* Now verify the true length of the payload and copy the decrypted
      part over the original data.  First get data length, and then padding
@@ -114,20 +123,20 @@ bool silc_message_payload_decrypt(unsigned char *data,
   SILC_GET16_MSB(len, dec + totlen);
   totlen += 2 + len;
   if (totlen + iv_len + mac_len + 2 > data_len) {
-    memset(dec, 0, data_len - iv_len - mac_len);
+    memset(dec, 0, dlen);
     silc_free(dec);
     return FALSE;
   }
   SILC_GET16_MSB(len, dec + totlen);
   totlen += 2 + len;
   if (totlen + iv_len + mac_len > data_len) {
-    memset(dec, 0, data_len - iv_len - mac_len);
+    memset(dec, 0, dlen);
     silc_free(dec);
     return FALSE;
   }
 
   memcpy(data, dec, totlen);
-  memset(dec, 0, data_len - iv_len - mac_len);
+  memset(dec, 0, dlen);
   silc_free(dec);
 
   return TRUE;