5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
19 /* Implementation of the Message Payload used as channel messages and
24 #include "silcmessage.h"
26 /*************************** Types and definitions **************************/
28 /* Calculates padding length for message payload */
29 #define SILC_MESSAGE_PAD(__payloadlen) (16 - ((__payloadlen) % 16))
31 /* Header length plus maximum padding length */
32 #define SILC_MESSAGE_HLEN 6 + 16
34 /* Maximum message length */
35 #define SILC_MESSAGE_MAX_LEN SILC_PACKET_MAX_LEN - SILC_MESSAGE_HLEN - 16
37 /* Payload encoding context */
42 SilcMessagePayloadEncoded encoded;
44 SilcMessageFlags flags;
45 SilcPublicKey public_key;
46 SilcPrivateKey private_key;
54 SilcUInt16 payload_len;
60 /************************* Static utility functions *************************/
63 silc_message_payload_encode_final(SilcBuffer buffer,
64 SilcMessageFlags flags,
69 SilcUInt32 payload_len,
74 SilcMessagePayloadEncoded encoded,
77 /* Returns the data length that fits to the packet. If data length is too
78 big it will be truncated to fit to the payload. */
81 SilcUInt32 silc_message_payload_datalen(SilcUInt32 data_len,
82 SilcUInt32 header_len,
84 SilcPublicKey public_key,
85 SilcPrivateKey private_key)
87 SilcUInt32 pklen = (flags & SILC_MESSAGE_FLAG_SIGNED && public_key ?
88 silc_pkcs_public_key_get_len(public_key) : 0);
89 SilcUInt32 prlen = (flags & SILC_MESSAGE_FLAG_SIGNED ?
90 silc_pkcs_private_key_get_len(private_key) / 8 : 0);
91 SilcUInt32 dlen = data_len + SILC_MESSAGE_HLEN + header_len + pklen + prlen;
93 if (silc_unlikely(dlen > SILC_MESSAGE_MAX_LEN))
94 data_len -= (dlen - SILC_MESSAGE_MAX_LEN);
99 /* Free signed payload */
101 static void silc_message_signed_payload_free(SilcMessageSignedPayload sig)
103 if (sig->sign_data) {
104 memset(sig->sign_data, 0, sig->sign_len);
105 silc_free(sig->sign_data);
107 silc_free(sig->pk_data);
110 /* Parses the SILC_MESSAGE_FLAG_SIGNED Payload */
113 silc_message_signed_payload_parse(const unsigned char *data,
115 SilcMessageSignedPayload sig)
117 SilcBufferStruct buffer;
120 SILC_LOG_DEBUG(("Parsing SILC_MESSAGE_FLAG_SIGNED Payload"));
122 SILC_LOG_HEXDUMP(("sig payload"), (unsigned char *)data, data_len);
124 silc_buffer_set(&buffer, (unsigned char *)data, data_len);
126 /* Parse the payload */
127 ret = silc_buffer_unformat(&buffer,
128 SILC_STR_UI_SHORT(&sig->pk_len),
129 SILC_STR_UI_SHORT(&sig->pk_type),
131 if (ret == -1 || sig->pk_len > data_len - 4) {
132 SILC_LOG_DEBUG(("Malformed public key in SILC_MESSAGE_FLAG_SIGNED "
137 silc_buffer_pull(&buffer, 4);
138 ret = silc_buffer_unformat(&buffer,
139 SILC_STR_UI_XNSTRING_ALLOC(&sig->pk_data,
141 SILC_STR_UI16_NSTRING_ALLOC(&sig->sign_data,
144 if (ret == -1 || sig->sign_len > silc_buffer_len(&buffer) -
146 silc_message_signed_payload_free(sig);
147 SILC_LOG_DEBUG(("Malformed SILC_MESSAGE_FLAG_SIGNED Payload"));
150 silc_buffer_push(&buffer, 4);
152 /* Signature must be provided */
153 if (sig->sign_len < 1) {
154 SILC_LOG_DEBUG(("Malformed signature in SILC_MESSAGE_SIGNED_PAYLOAD "
156 silc_message_signed_payload_free(sig);
163 /* Encodes the data to be signed to SILC_MESSAGE_FLAG_SIGNED Payload */
166 silc_message_signed_encode_data(SilcStack stack,
167 const unsigned char *message_payload,
168 SilcUInt32 message_payload_len,
170 SilcUInt32 pk_len, SilcUInt32 pk_type)
174 sign = silc_buffer_salloc_size(stack, message_payload_len + 4 + pk_len);
178 silc_buffer_sformat(stack, sign,
179 SILC_STR_DATA(message_payload, message_payload_len),
180 SILC_STR_UI_SHORT(pk_len),
181 SILC_STR_UI_SHORT(pk_type),
185 silc_buffer_pull(sign, message_payload_len + 4);
186 silc_buffer_sformat(stack, sign,
187 SILC_STR_UI_XNSTRING(pk, pk_len),
189 silc_buffer_push(sign, message_payload_len + 4);
195 /* Signature callback */
197 void silc_message_signed_payload_encode_cb(SilcBool success,
198 const unsigned char *signature,
199 SilcUInt32 signature_len,
202 SilcMessageEncode *e = context;
203 SilcPKCSType pk_type;
204 SilcStack stack = e->stack;
205 SilcBuffer buffer, payload;
206 SilcMessageFlags flags;
210 SilcUInt32 iv_len, payload_len;
212 SilcMessagePayloadEncoded encoded;
213 void *encoded_context;
216 e->encoded(NULL, e->context);
217 silc_buffer_sfree(stack, e->sign);
218 silc_sfree(stack, e->pk);
219 silc_sfree(stack, e);
220 silc_stack_free(stack);
224 pk_type = silc_pkcs_get_type(e->private_key);
226 /* Encode the SILC_MESSAGE_FLAG_SIGNED Payload */
227 buffer = silc_buffer_salloc_size(stack, 4 + e->pk_len + 2 + signature_len);
229 e->encoded(NULL, e->context);
230 silc_buffer_sfree(stack, e->sign);
231 silc_sfree(stack, e->pk);
232 silc_sfree(stack, e);
233 silc_stack_free(stack);
237 silc_buffer_sformat(stack, buffer,
238 SILC_STR_UI_SHORT(e->pk_len),
239 SILC_STR_UI_SHORT(pk_type),
242 if (e->pk_len && e->pk) {
243 silc_buffer_pull(buffer, 4);
244 silc_buffer_sformat(stack, buffer,
245 SILC_STR_DATA(e->pk, e->pk_len),
247 silc_buffer_push(buffer, 4);
250 silc_buffer_pull(buffer, 4 + e->pk_len);
251 silc_buffer_sformat(stack, buffer,
252 SILC_STR_UI_SHORT(signature_len),
253 SILC_STR_DATA(signature, signature_len),
255 silc_buffer_push(buffer, 4 + e->pk_len);
257 SILC_LOG_HEXDUMP(("SIG payload"), buffer->data, silc_buffer_len(buffer));
265 payload_len = e->payload_len;
268 encoded = e->encoded;
269 encoded_context = e->context;
271 silc_sfree(stack, e->pk);
272 silc_buffer_sfree(stack, e->sign);
273 silc_sfree(stack, e);
275 /* Finalize message payload encoding */
276 silc_message_payload_encode_final(payload, flags, cipher, hmac,
277 iv, iv_len, payload_len,
278 sid, rid, stack, buffer,
279 encoded, encoded_context);
282 /* Encodes the SILC_MESSAGE_FLAG_SIGNED Payload and computes the digital
285 static SilcAsyncOperation
286 silc_message_signed_payload_encode(SilcBuffer payload,
287 SilcMessageEncode *e)
289 SilcAsyncOperation op;
291 unsigned char *pk = NULL;
292 SilcUInt32 pk_len = 0;
294 SilcStack stack = e->stack;
295 SilcHash hash = e->hash;
296 SilcPublicKey public_key = e->public_key;
297 SilcPrivateKey private_key = e->private_key;
298 unsigned char *message_payload;
299 SilcUInt16 message_payload_len;
301 message_payload = payload->head;
302 message_payload_len = silc_buffer_headlen(payload);
304 if (!message_payload || !message_payload_len || !private_key || !hash) {
305 e->encoded(NULL, e->context);
306 silc_sfree(stack, e);
307 silc_stack_free(stack);
312 e->pk = pk = silc_pkcs_public_key_encode(stack, public_key, &pk_len);
314 e->encoded(NULL, e->context);
315 silc_sfree(stack, e);
316 silc_stack_free(stack);
321 pk_type = silc_pkcs_get_type(private_key);
323 /* Encode the data to be signed */
324 e->sign = sign = silc_message_signed_encode_data(stack, message_payload,
326 pk, pk_len, pk_type);
328 e->encoded(NULL, e->context);
329 silc_sfree(stack, pk);
330 silc_sfree(stack, e);
331 silc_stack_free(stack);
335 /* Compute signature */
336 op = silc_pkcs_sign(private_key, sign->data, silc_buffer_len(sign),
337 TRUE, hash, silc_message_signed_payload_encode_cb, e);
342 /***************************** Payload parsing ******************************/
344 /* Decrypts the Message Payload. The `data' is the actual Message Payload. */
346 SilcBool silc_message_payload_decrypt(unsigned char *data,
348 SilcBool private_message,
352 unsigned char *sender_id,
353 SilcUInt32 sender_id_len,
354 unsigned char *receiver_id,
355 SilcUInt32 receiver_id_len,
358 SilcUInt32 mac_len, iv_len = 0, block_len;
359 SilcUInt16 len, totlen;
360 unsigned char mac[32], *ivp;
362 mac_len = silc_hmac_len(hmac);
363 block_len = silc_cipher_get_block_len(cipher);
365 /* IV is present for all channel messages, and private messages when
366 static key (pre-shared key) is used. */
367 if (!private_message || (private_message && static_key))
370 if (silc_unlikely(data_len < (mac_len + iv_len + block_len)))
373 if (silc_likely(check_mac)) {
374 /* Check the MAC of the message */
375 SILC_LOG_DEBUG(("Checking message MAC"));
376 silc_hmac_init(hmac);
377 silc_hmac_update(hmac, data, data_len - mac_len);
378 silc_hmac_update(hmac, sender_id, sender_id_len);
379 silc_hmac_update(hmac, receiver_id, receiver_id_len);
380 silc_hmac_final(hmac, mac, &mac_len);
381 if (silc_unlikely(memcmp(data + (data_len - mac_len), mac, mac_len))) {
382 /* Check for old style (version 1.2) message MAC. Remove this check
384 silc_hmac_init(hmac);
385 silc_hmac_update(hmac, data, data_len - mac_len);
386 silc_hmac_final(hmac, mac, &mac_len);
387 if (silc_unlikely(memcmp(data + (data_len - mac_len), mac, mac_len))) {
388 SILC_LOG_DEBUG(("Message MAC does not match"));
392 SILC_LOG_DEBUG(("MAC is Ok"));
395 /* Decrypt first only one block to get the header and then rest of
396 the data. This is done because there might be unencrypted data at
397 the end and we don't know the encrypted length yet. */
399 /* Get pointer to the IV */
400 ivp = (iv_len ? data + (data_len - iv_len - mac_len) :
401 silc_cipher_get_iv(cipher));
404 if (silc_unlikely(!silc_cipher_decrypt(cipher, data, data, block_len,
410 /* Get the payload length and decrypt rest */
412 SILC_GET16_MSB(len, data + totlen);
414 if (silc_unlikely(totlen + iv_len + mac_len + 2 > data_len))
417 if (totlen >= block_len)
418 if (silc_unlikely(!silc_cipher_decrypt(cipher, data + block_len,
420 (totlen - block_len) +
421 SILC_MESSAGE_PAD(totlen), ivp))) {
429 /* Parses Message Payload returning new payload structure. This also
430 decrypts it and checks the MAC. */
433 silc_message_payload_parse(unsigned char *payload,
434 SilcUInt32 payload_len,
435 SilcBool private_message,
439 unsigned char *sender_id,
440 SilcUInt32 sender_id_len,
441 unsigned char *receiver_id,
442 SilcUInt32 receiver_id_len,
444 SilcBool no_allocation,
445 SilcMessagePayload message)
447 SilcBufferStruct buffer;
448 SilcMessagePayload newp = NULL;
450 SilcUInt32 mac_len = 0, iv_len = 0;
452 SILC_LOG_DEBUG(("Parsing Message Payload"));
454 silc_buffer_set(&buffer, payload, payload_len);
456 /* Decrypt the payload */
457 if (silc_likely(cipher)) {
458 ret = silc_message_payload_decrypt(buffer.data, silc_buffer_len(&buffer),
459 private_message, static_key,
460 cipher, hmac, sender_id,
461 sender_id_len, receiver_id,
462 receiver_id_len, TRUE);
463 if (silc_unlikely(ret == FALSE))
467 if (silc_likely(hmac))
468 mac_len = silc_hmac_len(hmac);
470 /* IV is present for all channel messages, and private messages when
471 static key (pre-shared key) is used. */
472 if (cipher && (!private_message || (private_message && static_key)))
473 iv_len = silc_cipher_get_block_len(cipher);
476 newp = message = silc_calloc(1, sizeof(*newp));
477 if (silc_unlikely(!newp))
480 memset(message, 0, sizeof(*message));
481 message->allocated = (stack || no_allocation ? FALSE : TRUE);
483 /* Parse the Message Payload. */
485 ret = silc_buffer_sunformat(stack, &buffer,
486 SILC_STR_UI_SHORT(&message->flags),
487 SILC_STR_UI16_NSTRING_ALLOC(&message->data,
489 SILC_STR_UI16_NSTRING_ALLOC(&message->pad,
493 ret = silc_buffer_unformat(&buffer,
494 SILC_STR_UI_SHORT(&message->flags),
495 SILC_STR_UI16_NSTRING(&message->data,
497 SILC_STR_UI16_NSTRING(&message->pad,
500 if (silc_unlikely(ret == -1))
503 if (silc_unlikely((message->data_len > silc_buffer_len(&buffer) -
504 6 - mac_len - iv_len) ||
505 (message->pad_len + message->data_len >
506 silc_buffer_len(&buffer) - 6 - mac_len - iv_len))) {
507 SILC_LOG_ERROR(("Incorrect Message Payload in packet"));
511 /* Parse Signed Message Payload if provided */
512 if (message->flags & SILC_MESSAGE_FLAG_SIGNED &&
513 message->data_len + message->pad_len + 6 + mac_len +
514 iv_len < silc_buffer_len(&buffer)) {
515 if (!silc_message_signed_payload_parse(buffer.data + 6 +
518 silc_buffer_len(&buffer) -
519 iv_len - mac_len - 6 -
526 /* Parse MAC from the payload */
528 message->mac = buffer.data + (silc_buffer_len(&buffer) - mac_len);
534 silc_message_payload_free(newp);
539 /***************************** Payload encoding *****************************/
541 /* This function is used to encrypt the Messsage Payload which is
542 the `data' and `data_len'. This is used internally by the Message
543 Payload encoding routines but application may call this too if needed.
544 The `true_len' is the data length which is used to create MAC out of. */
546 SilcBool silc_message_payload_encrypt(unsigned char *data,
555 unsigned char sid[32], rid[32];
556 SilcUInt32 sid_len = 0, rid_len = 0;
558 /* Encrypt payload of the packet */
559 if (silc_unlikely(!silc_cipher_encrypt(cipher, data, data, data_len, iv)))
563 silc_id_id2str(&sender_id->u.client_id, SILC_ID_CLIENT, sid, sizeof(sid),
565 if (receiver_id->type == SILC_ID_CLIENT)
566 silc_id_id2str(&receiver_id->u.client_id, SILC_ID_CLIENT, rid,
567 sizeof(rid), &rid_len);
568 else if (receiver_id->type == SILC_ID_CHANNEL)
569 silc_id_id2str(&receiver_id->u.channel_id, SILC_ID_CHANNEL, rid,
570 sizeof(rid), &rid_len);
572 /* Compute the MAC of the encrypted message data */
573 silc_hmac_init(hmac);
574 silc_hmac_update(hmac, data, true_len);
575 silc_hmac_update(hmac, sid, sid_len);
576 silc_hmac_update(hmac, rid, rid_len);
577 silc_hmac_final(hmac, data + true_len, NULL);
582 /* Encrypt message payload */
584 static int silc_message_payload_encode_encrypt(SilcStack stack,
586 void *value, void *context)
588 SilcMessageEncode *e = context;
591 if (!e->cipher || !e->hmac)
594 mac_len = silc_hmac_len(e->hmac);
595 if (silc_unlikely(!silc_buffer_enlarge(buffer, mac_len)))
598 if (silc_unlikely(!silc_message_payload_encrypt(buffer->head,
600 silc_buffer_headlen(buffer),
601 e->iv, &e->sid, &e->rid,
602 e->cipher, e->hmac)))
608 /* Finalize message payload encoding */
611 silc_message_payload_encode_final(SilcBuffer buffer,
612 SilcMessageFlags flags,
617 SilcUInt32 payload_len,
621 SilcBuffer signature,
622 SilcMessagePayloadEncoded encoded,
631 e.rid = *receiver_id;
633 e.payload_len = payload_len;
636 if (silc_buffer_format(buffer,
637 SILC_STR_DATA(signature ?
638 silc_buffer_data(signature) : NULL,
640 silc_buffer_len(signature) : 0),
641 SILC_STR_DATA(iv, iv_len),
642 SILC_STR_FUNC(silc_message_payload_encode_encrypt,
645 silc_buffer_sfree(stack, buffer);
646 encoded(NULL, context);
650 /* Deliver message payload */
651 silc_buffer_start(buffer);
652 encoded(buffer, context);
654 silc_buffer_sfree(stack, buffer);
655 silc_buffer_sfree(stack, signature);
656 silc_stack_free(stack);
659 /* Encodes Message Payload into a buffer and returns it. */
662 silc_message_payload_encode(SilcMessageFlags flags,
663 const unsigned char *data,
665 SilcBool generate_iv,
666 SilcBool private_message,
670 SilcPublicKey public_key,
671 SilcPrivateKey private_key,
676 SilcMessagePayloadEncoded encoded,
679 SilcUInt32 pad_len = 0, mac_len = 0, iv_len = 0;
680 unsigned char pad[16], iv[SILC_CIPHER_MAX_IV_SIZE];
684 SILC_LOG_DEBUG(("Encoding Message Payload"));
686 if (silc_unlikely(!data_len)) {
687 encoded(NULL, context);
690 if (silc_unlikely(!private_message && (!cipher || !hmac))) {
691 encoded(NULL, context);
695 stack = silc_stack_alloc(0, stack ? stack : silc_crypto_stack());
697 buffer = silc_buffer_salloc(stack, 0);
698 if (silc_unlikely(!buffer)) {
699 encoded(NULL, context);
700 silc_stack_free(stack);
704 /* For channel messages IV is always generated */
705 if (!private_message && !generate_iv)
709 if (cipher && generate_iv) {
710 iv_len = silc_cipher_get_block_len(cipher);
712 for (i = 0; i < iv_len; i++) iv[i] = silc_rng_get_byte_fast(rng);
714 for (i = 0; i < iv_len; i++) iv[i] = silc_rng_global_get_byte_fast();
719 mac_len = silc_hmac_len(hmac);
720 data_len = silc_message_payload_datalen(data_len, mac_len + iv_len, flags,
721 public_key, private_key);
723 /* Calculate length of padding. IV is not included into the calculation
724 since it is not encrypted. */
725 pad_len = SILC_MESSAGE_PAD(6 + data_len);
727 /* Generate padding */
730 for (i = 0; i < pad_len; i++) pad[i] = silc_rng_get_byte_fast(rng);
732 for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte_fast();
736 /* Encode the Message Payload */
737 if (silc_buffer_format(buffer,
739 SILC_STR_UI_SHORT(flags),
740 SILC_STR_UI_SHORT(data_len),
741 SILC_STR_DATA(data, data_len),
742 SILC_STR_UI_SHORT(pad_len),
743 SILC_STR_DATA(pad, pad_len),
745 silc_buffer_sfree(stack, buffer);
746 encoded(NULL, context);
747 silc_stack_free(stack);
751 if (flags & SILC_MESSAGE_FLAG_SIGNED) {
752 SilcMessageEncode *e = silc_scalloc(stack, 1, sizeof(*e));
754 silc_buffer_sfree(stack, buffer);
755 encoded(NULL, context);
756 silc_stack_free(stack);
763 e->public_key = public_key;
764 e->private_key = private_key;
769 e->rid = *receiver_id;
770 e->iv = iv_len ? iv : NULL;
772 e->payload_len = 6 + data_len + pad_len;
773 e->encoded = encoded;
774 e->context = context;
776 /* Compute signature */
777 return silc_message_signed_payload_encode(buffer, e);
781 silc_message_payload_encode_final(buffer, flags, cipher, hmac,
782 iv_len ? iv : NULL, iv_len,
783 6 + data_len + pad_len,
784 sender_id, receiver_id, stack, NULL,
789 /* Free's Message Payload */
791 void silc_message_payload_free(SilcMessagePayload payload)
793 silc_message_signed_payload_free(&payload->sig);
795 memset(payload->data, 0, payload->data_len);
796 if (payload->allocated)
797 silc_free(payload->data);
799 if (payload->allocated) {
800 silc_free(payload->pad);
807 SilcMessageFlags silc_message_get_flags(SilcMessagePayload payload)
809 return payload->flags;
814 unsigned char *silc_message_get_data(SilcMessagePayload payload,
815 SilcUInt32 *data_len)
818 *data_len = payload->data_len;
819 return payload->data;
822 /* Return MAC. The caller knows the length of the MAC */
824 unsigned char *silc_message_get_mac(SilcMessagePayload payload)
829 /* Verify the signature in SILC_MESSAGE_FLAG_SIGNED Payload */
832 silc_message_signed_verify(SilcMessagePayload message,
833 SilcPublicKey remote_public_key,
835 SilcAuthResultCb result,
838 SilcAsyncOperation op;
839 SilcBuffer sign, tmp;
840 SilcStack stack = NULL;
841 SilcMessageSignedPayload sig = &message->sig;
843 if (!(message->flags & SILC_MESSAGE_FLAG_SIGNED) ||
844 !sig->sign_len || !remote_public_key || !hash) {
845 result(FALSE, context);
849 if (silc_crypto_stack())
850 stack = silc_stack_alloc(0, silc_crypto_stack());
852 /* Generate the signature verification data, the Message Payload */
853 tmp = silc_buffer_salloc_size(stack,
854 6 + message->data_len + message->pad_len);
855 silc_buffer_sformat(stack, tmp,
856 SILC_STR_UI_SHORT(message->flags),
857 SILC_STR_UI_SHORT(message->data_len),
858 SILC_STR_DATA(message->data, message->data_len),
859 SILC_STR_UI_SHORT(message->pad_len),
860 SILC_STR_DATA(message->pad, message->pad_len),
862 sign = silc_message_signed_encode_data(stack, tmp->data, silc_buffer_len(tmp),
863 sig->pk_data, sig->pk_len,
865 silc_buffer_clear(tmp);
866 silc_buffer_sfree(stack, tmp);
869 result(FALSE, context);
870 silc_stack_free(stack);
874 /* Verify the authentication data */
875 op = silc_pkcs_verify(remote_public_key, sig->sign_data, sig->sign_len,
876 silc_buffer_data(sign), silc_buffer_len(sign), hash,
879 silc_buffer_clear(sign);
880 silc_buffer_sfree(stack, sign);
881 silc_stack_free(stack);
886 /* Return the public key from the payload */
889 silc_message_signed_get_public_key(SilcMessagePayload payload,
890 const unsigned char **pk_data,
891 SilcUInt32 *pk_data_len)
894 SilcMessageSignedPayload sig = &payload->sig;
899 if (!silc_pkcs_public_key_alloc(sig->pk_type, sig->pk_data,
904 *pk_data = sig->pk_data;
906 *pk_data_len = sig->pk_len;