From d594e79415a2619ed8d2b7705ff69678fc861c65 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Wed, 14 Feb 2007 14:50:41 +0000 Subject: [PATCH] Added support for computing message payload MAC in the new way (SILC Protocol 1.3 changte). Backwards support for old way remains. --- lib/silccore/silcmessage.c | 57 ++++++++++++++++++++++++++++++++++++-- lib/silccore/silcmessage.h | 37 ++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/lib/silccore/silcmessage.c b/lib/silccore/silcmessage.c index 2bb3ef9e..ae257eb2 100644 --- a/lib/silccore/silcmessage.c +++ b/lib/silccore/silcmessage.c @@ -44,6 +44,8 @@ typedef struct { SilcHmac hmac; unsigned char *iv; SilcUInt16 payload_len; + SilcID *sid; + SilcID *rid; } SilcMessageEncode; @@ -268,6 +270,10 @@ SilcBool silc_message_payload_decrypt(unsigned char *data, SilcBool static_key, SilcCipher cipher, SilcHmac hmac, + unsigned char *sender_id, + SilcUInt32 sender_id_len, + unsigned char *receiver_id, + SilcUInt32 receiver_id_len, SilcBool check_mac) { SilcUInt32 mac_len, iv_len = 0, block_len; @@ -290,10 +296,23 @@ SilcBool silc_message_payload_decrypt(unsigned char *data, SILC_LOG_DEBUG(("Checking message MAC")); silc_hmac_init(hmac); silc_hmac_update(hmac, data, data_len - mac_len); + silc_hmac_update(hmac, sender_id, sender_id_len); + silc_hmac_update(hmac, receiver_id, receiver_id_len); silc_hmac_final(hmac, mac, &mac_len); if (silc_unlikely(memcmp(data + (data_len - mac_len), mac, mac_len))) { +#if 0 SILC_LOG_DEBUG(("Message MAC does not match")); return FALSE; +#else + /* Check for old style message MAC. Remove this check at some point. */ + silc_hmac_init(hmac); + silc_hmac_update(hmac, data, data_len - mac_len); + silc_hmac_final(hmac, mac, &mac_len); + if (silc_unlikely(memcmp(data + (data_len - mac_len), mac, mac_len))) { + SILC_LOG_DEBUG(("Message MAC does not match")); +#endif + return FALSE; + } } SILC_LOG_DEBUG(("MAC is Ok")); } @@ -342,6 +361,10 @@ silc_message_payload_parse(unsigned char *payload, SilcBool static_key, SilcCipher cipher, SilcHmac hmac, + unsigned char *sender_id, + SilcUInt32 sender_id_len, + unsigned char *receiver_id, + SilcUInt32 receiver_id_len, SilcStack stack, SilcBool no_allocation, SilcMessagePayload message) @@ -359,7 +382,9 @@ silc_message_payload_parse(unsigned char *payload, if (silc_likely(cipher)) { ret = silc_message_payload_decrypt(buffer.data, silc_buffer_len(&buffer), private_message, static_key, - cipher, hmac, TRUE); + cipher, hmac, sender_id, + sender_id_len, receiver_id, + receiver_id_len, TRUE); if (silc_unlikely(ret == FALSE)) return NULL; } @@ -447,16 +472,39 @@ SilcBool silc_message_payload_encrypt(unsigned char *data, SilcUInt32 data_len, SilcUInt32 true_len, unsigned char *iv, + SilcID *sender_id, + SilcID *receiver_id, SilcCipher cipher, SilcHmac hmac) { +#if 0 + unsigned char sid[32], rid[32]; + SilcUInt32 sid_len = 0, rid_len = 0; +#endif /* 0 */ + /* Encrypt payload of the packet */ if (silc_unlikely(!silc_cipher_encrypt(cipher, data, data, data_len, iv))) return FALSE; +#if 0 /* For now this is disabled. Enable at 1.1.x or 1.2 at the latest. */ + /* Encode IDs */ + silc_id_id2str(&sender_id->u.client_id, SILC_ID_CLIENT, sid, sizeof(sid), + &sid_len); + if (receiver_id->type == SILC_ID_CLIENT) + silc_id_id2str(&receiver_id->u.client_id, SILC_ID_CLIENT, rid, + sizeof(rid), &rid_len); + else if (receiver_id->type == SILC_ID_CHANNEL) + silc_id_id2str(&receiver_id->u.channel_id, SILC_ID_CHANNEL, rid, + sizeof(rid), &rid_len); +#endif /* 0 */ + /* Compute the MAC of the encrypted message data */ silc_hmac_init(hmac); silc_hmac_update(hmac, data, true_len); +#if 0 + silc_hmac_update(hmac, sid, sid_len); + silc_hmac_update(hmac, rid, rid_len); +#endif /* 0 */ silc_hmac_final(hmac, data + true_len, NULL); return TRUE; @@ -480,7 +528,8 @@ static int silc_message_payload_encode_encrypt(SilcBuffer buffer, if (silc_unlikely(!silc_message_payload_encrypt(buffer->head, e->payload_len, silc_buffer_headlen(buffer), - e->iv, e->cipher, e->hmac))) + e->iv, e->sid, e->rid, + e->cipher, e->hmac))) return -1; return mac_len; @@ -531,6 +580,8 @@ SilcBuffer silc_message_payload_encode(SilcMessageFlags flags, SilcPublicKey public_key, SilcPrivateKey private_key, SilcHash hash, + SilcID *sender_id, + SilcID *receiver_id, SilcBuffer buffer) { SilcUInt32 pad_len = 0, mac_len = 0, iv_len = 0; @@ -591,6 +642,8 @@ SilcBuffer silc_message_payload_encode(SilcMessageFlags flags, e.hash = hash; e.cipher = cipher; e.hmac = hmac; + e.sid = sender_id; + e.rid = receiver_id; e.iv = iv_len ? iv : NULL; e.payload_len = 6 + data_len + pad_len; diff --git a/lib/silccore/silcmessage.h b/lib/silccore/silcmessage.h index e51c3009..99e9d988 100644 --- a/lib/silccore/silcmessage.h +++ b/lib/silccore/silcmessage.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2006 Pekka Riikonen + Copyright (C) 1997 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -93,6 +93,10 @@ typedef SilcUInt16 SilcMessageFlags; * SilcBool static_key, * SilcCipher cipher, * SilcHmac hmac, + * unsigned char *sender_id, + * SilcUInt32 sender_id_len, + * unsigned char *receiver_id, + * SilcUInt32 receiver_id_len, * SilcBool check_mac); * * DESCRIPTION @@ -105,6 +109,9 @@ typedef SilcUInt16 SilcMessageFlags; * (Key Agreement was done for the key) then it MUST be FALSE. For * channel messages the `static_key' is ignored. * + * The `sender_id' and `receiver_id' are the IDs from the packet header + * of the packet where this message payload was received. + * * This is usually used by the Message Payload interface itself but can * be called by the appliation if separate decryption process is required. * For example server might need to call this directly in some @@ -118,6 +125,10 @@ SilcBool silc_message_payload_decrypt(unsigned char *data, SilcBool static_key, SilcCipher cipher, SilcHmac hmac, + unsigned char *sender_id, + SilcUInt32 sender_id_len, + unsigned char *receiver_id, + SilcUInt32 receiver_id_len, SilcBool check_mac); /****f* silccore/SilcMessageAPI/silc_message_payload_parse @@ -131,6 +142,10 @@ SilcBool silc_message_payload_decrypt(unsigned char *data, * SilcBool static_key, * SilcCipher cipher, * SilcHmac hmac, + * unsigned char *sender_id, + * SilcUInt32 sender_id_len, + * unsigned char *receiver_id, + * SilcUInt32 receiver_id_len, * SilcStack stack, * SilcBool no_allocation, * SilcMessagePayload message); @@ -151,6 +166,9 @@ SilcBool silc_message_payload_decrypt(unsigned char *data, * then this assumes that the packet was decrypted with session keys * (no private message key) and this merely decodes the payload. * + * The `sender_id' and `receiver_id' are the IDs from the packet header + * of the packet where this message payload was received. + * * If the `message' is non-NULL then that pre-allocated context is * used in parsing. Same context is returned. Otherwise new context * is allocated and returned. If the `stack' is non-NULL then memory @@ -167,6 +185,10 @@ silc_message_payload_parse(unsigned char *payload, SilcBool static_key, SilcCipher cipher, SilcHmac hmac, + unsigned char *sender_id, + SilcUInt32 sender_id_len, + unsigned char *receiver_id, + SilcUInt32 receiver_id_len, SilcStack stack, SilcBool no_allocation, SilcMessagePayload message); @@ -179,6 +201,8 @@ silc_message_payload_parse(unsigned char *payload, * SilcUInt32 data_len, * SilcUInt32 true_len, * unsigned char *iv, + * SilcID *sender_id, + * SilcID *receiver_id, * SilcCipher cipher, * SilcHmac hmac); * @@ -188,6 +212,8 @@ silc_message_payload_parse(unsigned char *payload, * the `data' and `data_len'. The `data_len' is the data length which * is used to create MAC out of. The `data' MUST have additional space * after `true_len' bytes for the MAC which is appended to the data. + * The `sender_id' is the ID message sender and `receiver_id' is ID of + * message receiver. * * This is usually used by the Message Payload interface itself but can * be called by the appliation if separate encryption process is required. @@ -200,6 +226,8 @@ SilcBool silc_message_payload_encrypt(unsigned char *data, SilcUInt32 data_len, SilcUInt32 true_len, unsigned char *iv, + SilcID *sender_id, + SilcID *receiver_id, SilcCipher cipher, SilcHmac hmac); @@ -218,6 +246,8 @@ SilcBool silc_message_payload_encrypt(unsigned char *data, * SilcPublicKey public_key, * SilcPrivateKey private_key, * SilcHash hash, + * SilcID *sender_id, + * SilcID *receiver_id, * SilcBuffer buffer); * * DESCRIPTION @@ -248,6 +278,9 @@ SilcBool silc_message_payload_encrypt(unsigned char *data, * be included in the message. The `private_message' and `hash' MUST * be provided. The `hash' SHOULD be SHA1. * + * The `sender_id' is the ID message sender and `receiver_id' is ID of + * message receiver. + * * If the `buffer' is non-NULL then the payload will be encoded into * that buffer. The same buffer is returned. Otherwise new buffer is * allocated and returned. The `buffer' will be automatically enlarged @@ -265,6 +298,8 @@ SilcBuffer silc_message_payload_encode(SilcMessageFlags flags, SilcPublicKey public_key, SilcPrivateKey private_key, SilcHash hash, + SilcID *sender_id, + SilcID *receiver_id, SilcBuffer buffer); /****f* silccore/SilcMessageAPI/silc_message_payload_free -- 2.24.0