From 3231122d9702366d9018efa5b65e3f5b38036e6b Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Wed, 4 Dec 2002 16:30:17 +0000 Subject: [PATCH] Fixed decryption length calculation to use multiple by blocksize length. --- CHANGES | 6 ++++++ lib/silccore/silcmessage.c | 33 +++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 66528327..8c312177 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +Wed Dec 4 18:29:13 EET 2002 Pekka Riikonen + + * 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 * Fixed founder key sending in CMODE command in client. diff --git a/lib/silccore/silcmessage.c b/lib/silccore/silcmessage.c index 66bd1b98..fa9181c3 100644 --- a/lib/silccore/silcmessage.c +++ b/lib/silccore/silcmessage.c @@ -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; -- 2.24.0