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;
55 SilcUInt16 payload_len;
61 /************************* Static utility functions *************************/
64 silc_message_payload_encode_final(SilcBuffer buffer,
65 SilcMessageFlags flags,
70 SilcUInt32 payload_len,
75 SilcMessagePayloadEncoded encoded,
78 /* Returns the data length that fits to the packet. If data length is too
79 big it will be truncated to fit to the payload. */
82 SilcUInt32 silc_message_payload_datalen(SilcUInt32 data_len,
83 SilcUInt32 header_len,
85 SilcPublicKey public_key,
86 SilcPrivateKey private_key)
88 SilcUInt32 pklen = (flags & SILC_MESSAGE_FLAG_SIGNED && public_key ?
89 silc_pkcs_public_key_get_len(public_key) : 0);
90 SilcUInt32 prlen = (flags & SILC_MESSAGE_FLAG_SIGNED ?
91 silc_pkcs_private_key_get_len(private_key) / 8 : 0);
92 SilcUInt32 dlen = data_len + SILC_MESSAGE_HLEN + header_len + pklen + prlen;
94 if (silc_unlikely(dlen > SILC_MESSAGE_MAX_LEN))
95 data_len -= (dlen - SILC_MESSAGE_MAX_LEN);
100 /* Free signed payload */
102 static void silc_message_signed_payload_free(SilcMessageSignedPayload sig)
104 if (sig->sign_data) {
105 memset(sig->sign_data, 0, sig->sign_len);
106 silc_free(sig->sign_data);
108 silc_free(sig->pk_data);
111 /* Parses the SILC_MESSAGE_FLAG_SIGNED Payload */
114 silc_message_signed_payload_parse(const unsigned char *data,
116 SilcMessageSignedPayload sig)
118 SilcBufferStruct buffer;
121 SILC_LOG_DEBUG(("Parsing SILC_MESSAGE_FLAG_SIGNED Payload"));
123 SILC_LOG_HEXDUMP(("sig payload"), (unsigned char *)data, data_len);
125 silc_buffer_set(&buffer, (unsigned char *)data, data_len);
127 /* Parse the payload */
128 ret = silc_buffer_unformat(&buffer,
129 SILC_STR_UI_SHORT(&sig->pk_len),
130 SILC_STR_UI_SHORT(&sig->pk_type),
132 if (ret == -1 || sig->pk_len > data_len - 4) {
133 SILC_LOG_DEBUG(("Malformed public key in SILC_MESSAGE_FLAG_SIGNED "
138 silc_buffer_pull(&buffer, 4);
139 ret = silc_buffer_unformat(&buffer,
140 SILC_STR_UI_XNSTRING_ALLOC(&sig->pk_data,
142 SILC_STR_UI16_NSTRING_ALLOC(&sig->sign_data,
145 if (ret == -1 || sig->sign_len > silc_buffer_len(&buffer) -
147 silc_message_signed_payload_free(sig);
148 SILC_LOG_DEBUG(("Malformed SILC_MESSAGE_FLAG_SIGNED Payload"));
151 silc_buffer_push(&buffer, 4);
153 /* Signature must be provided */
154 if (sig->sign_len < 1) {
155 SILC_LOG_DEBUG(("Malformed signature in SILC_MESSAGE_SIGNED_PAYLOAD "
157 silc_message_signed_payload_free(sig);
164 /* Encodes the data to be signed to SILC_MESSAGE_FLAG_SIGNED Payload */
167 silc_message_signed_encode_data(SilcStack stack,
168 const unsigned char *message_payload,
169 SilcUInt32 message_payload_len,
171 SilcUInt32 pk_len, SilcUInt32 pk_type)
175 sign = silc_buffer_salloc_size(stack, message_payload_len + 4 + pk_len);
179 silc_buffer_sformat(stack, sign,
180 SILC_STR_DATA(message_payload, message_payload_len),
181 SILC_STR_UI_SHORT(pk_len),
182 SILC_STR_UI_SHORT(pk_type),
186 silc_buffer_pull(sign, message_payload_len + 4);
187 silc_buffer_sformat(stack, sign,
188 SILC_STR_UI_XNSTRING(pk, pk_len),
190 silc_buffer_push(sign, message_payload_len + 4);
196 /* Signature callback */
198 void silc_message_signed_payload_encode_cb(SilcBool success,
199 const unsigned char *signature,
200 SilcUInt32 signature_len,
203 SilcMessageEncode *e = context;
204 SilcPKCSType pk_type;
205 SilcStack stack = e->stack;
206 SilcBuffer buffer, payload;
207 SilcMessageFlags flags;
211 SilcUInt32 iv_len, payload_len;
213 SilcMessagePayloadEncoded encoded;
214 void *encoded_context;
217 e->encoded(NULL, e->context);
218 silc_buffer_sfree(stack, e->sign);
219 silc_sfree(stack, e->pk);
220 silc_sfree(stack, e);
221 silc_stack_free(stack);
225 pk_type = silc_pkcs_get_type(e->private_key);
227 /* Encode the SILC_MESSAGE_FLAG_SIGNED Payload */
228 buffer = silc_buffer_salloc_size(stack, 4 + e->pk_len + 2 + signature_len);
230 e->encoded(NULL, e->context);
231 silc_buffer_sfree(stack, e->sign);
232 silc_sfree(stack, e->pk);
233 silc_sfree(stack, e);
234 silc_stack_free(stack);
238 silc_buffer_sformat(stack, buffer,
239 SILC_STR_UI_SHORT(e->pk_len),
240 SILC_STR_UI_SHORT(pk_type),
243 if (e->pk_len && e->pk) {
244 silc_buffer_pull(buffer, 4);
245 silc_buffer_sformat(stack, buffer,
246 SILC_STR_DATA(e->pk, e->pk_len),
248 silc_buffer_push(buffer, 4);
251 silc_buffer_pull(buffer, 4 + e->pk_len);
252 silc_buffer_sformat(stack, buffer,
253 SILC_STR_UI_SHORT(signature_len),
254 SILC_STR_DATA(signature, signature_len),
256 silc_buffer_push(buffer, 4 + e->pk_len);
258 SILC_LOG_HEXDUMP(("SIG payload"), buffer->data, silc_buffer_len(buffer));
266 payload_len = e->payload_len;
269 encoded = e->encoded;
270 encoded_context = e->context;
272 silc_sfree(stack, e->pk);
273 silc_buffer_sfree(stack, e->sign);
274 silc_sfree(stack, e);
276 /* Finalize message payload encoding */
277 silc_message_payload_encode_final(payload, flags, cipher, hmac,
278 iv, iv_len, payload_len,
279 sid, rid, stack, buffer,
280 encoded, encoded_context);
283 /* Encodes the SILC_MESSAGE_FLAG_SIGNED Payload and computes the digital
286 static SilcAsyncOperation
287 silc_message_signed_payload_encode(SilcBuffer payload,
288 SilcMessageEncode *e)
290 SilcAsyncOperation op;
292 unsigned char *pk = NULL;
293 SilcUInt32 pk_len = 0;
295 SilcStack stack = e->stack;
296 SilcRng rng = e->rng;
297 SilcHash hash = e->hash;
298 SilcPublicKey public_key = e->public_key;
299 SilcPrivateKey private_key = e->private_key;
300 unsigned char *message_payload;
301 SilcUInt16 message_payload_len;
303 message_payload = payload->head;
304 message_payload_len = silc_buffer_headlen(payload);
306 if (!message_payload || !message_payload_len || !private_key || !hash) {
307 e->encoded(NULL, e->context);
308 silc_sfree(stack, e);
309 silc_stack_free(stack);
314 e->pk = pk = silc_pkcs_public_key_encode(stack, public_key, &pk_len);
316 e->encoded(NULL, e->context);
317 silc_sfree(stack, e);
318 silc_stack_free(stack);
323 pk_type = silc_pkcs_get_type(private_key);
325 /* Encode the data to be signed */
326 e->sign = sign = silc_message_signed_encode_data(stack, message_payload,
328 pk, pk_len, pk_type);
330 e->encoded(NULL, e->context);
331 silc_sfree(stack, pk);
332 silc_sfree(stack, e);
333 silc_stack_free(stack);
337 /* Compute signature */
338 op = silc_pkcs_sign(private_key, sign->data, silc_buffer_len(sign),
340 silc_message_signed_payload_encode_cb, e);
345 /***************************** Payload parsing ******************************/
347 /* Decrypts the Message Payload. The `data' is the actual Message Payload. */
349 SilcBool silc_message_payload_decrypt(unsigned char *data,
351 SilcBool private_message,
355 unsigned char *sender_id,
356 SilcUInt32 sender_id_len,
357 unsigned char *receiver_id,
358 SilcUInt32 receiver_id_len,
361 SilcUInt32 mac_len, iv_len = 0, block_len;
362 SilcUInt16 len, totlen;
363 unsigned char mac[32], *ivp;
365 mac_len = silc_hmac_len(hmac);
366 block_len = silc_cipher_get_block_len(cipher);
368 /* IV is present for all channel messages, and private messages when
369 static key (pre-shared key) is used. */
370 if (!private_message || (private_message && static_key))
373 if (silc_unlikely(data_len < (mac_len + iv_len + block_len)))
376 if (silc_likely(check_mac)) {
377 /* Check the MAC of the message */
378 SILC_LOG_DEBUG(("Checking message MAC"));
379 silc_hmac_init(hmac);
380 silc_hmac_update(hmac, data, data_len - mac_len);
381 silc_hmac_update(hmac, sender_id, sender_id_len);
382 silc_hmac_update(hmac, receiver_id, receiver_id_len);
383 silc_hmac_final(hmac, mac, &mac_len);
384 if (silc_unlikely(memcmp(data + (data_len - mac_len), mac, mac_len))) {
385 /* Check for old style (version 1.2) message MAC. Remove this check
387 silc_hmac_init(hmac);
388 silc_hmac_update(hmac, data, data_len - mac_len);
389 silc_hmac_final(hmac, mac, &mac_len);
390 if (silc_unlikely(memcmp(data + (data_len - mac_len), mac, mac_len))) {
391 SILC_LOG_DEBUG(("Message MAC does not match"));
395 SILC_LOG_DEBUG(("MAC is Ok"));
398 /* Decrypt first only one block to get the header and then rest of
399 the data. This is done because there might be unencrypted data at
400 the end and we don't know the encrypted length yet. */
402 /* Get pointer to the IV */
403 ivp = (iv_len ? data + (data_len - iv_len - mac_len) :
404 silc_cipher_get_iv(cipher));
407 if (silc_unlikely(!silc_cipher_decrypt(cipher, data, data, block_len,
413 /* Get the payload length and decrypt rest */
415 SILC_GET16_MSB(len, data + totlen);
417 if (silc_unlikely(totlen + iv_len + mac_len + 2 > data_len))
420 if (totlen >= block_len)
421 if (silc_unlikely(!silc_cipher_decrypt(cipher, data + block_len,
423 (totlen - block_len) +
424 SILC_MESSAGE_PAD(totlen), ivp))) {
432 /* Parses Message Payload returning new payload structure. This also
433 decrypts it and checks the MAC. */
436 silc_message_payload_parse(unsigned char *payload,
437 SilcUInt32 payload_len,
438 SilcBool private_message,
442 unsigned char *sender_id,
443 SilcUInt32 sender_id_len,
444 unsigned char *receiver_id,
445 SilcUInt32 receiver_id_len,
447 SilcBool no_allocation,
448 SilcMessagePayload message)
450 SilcBufferStruct buffer;
451 SilcMessagePayload newp = NULL;
453 SilcUInt32 mac_len = 0, iv_len = 0;
455 SILC_LOG_DEBUG(("Parsing Message Payload"));
457 silc_buffer_set(&buffer, payload, payload_len);
459 /* Decrypt the payload */
460 if (silc_likely(cipher)) {
461 ret = silc_message_payload_decrypt(buffer.data, silc_buffer_len(&buffer),
462 private_message, static_key,
463 cipher, hmac, sender_id,
464 sender_id_len, receiver_id,
465 receiver_id_len, TRUE);
466 if (silc_unlikely(ret == FALSE))
470 if (silc_likely(hmac))
471 mac_len = silc_hmac_len(hmac);
473 /* IV is present for all channel messages, and private messages when
474 static key (pre-shared key) is used. */
475 if (cipher && (!private_message || (private_message && static_key)))
476 iv_len = silc_cipher_get_block_len(cipher);
479 newp = message = silc_calloc(1, sizeof(*newp));
480 if (silc_unlikely(!newp))
483 memset(message, 0, sizeof(*message));
484 message->allocated = (stack || no_allocation ? FALSE : TRUE);
486 /* Parse the Message Payload. */
488 ret = silc_buffer_sunformat(stack, &buffer,
489 SILC_STR_UI_SHORT(&message->flags),
490 SILC_STR_UI16_NSTRING_ALLOC(&message->data,
492 SILC_STR_UI16_NSTRING_ALLOC(&message->pad,
496 ret = silc_buffer_unformat(&buffer,
497 SILC_STR_UI_SHORT(&message->flags),
498 SILC_STR_UI16_NSTRING(&message->data,
500 SILC_STR_UI16_NSTRING(&message->pad,
503 if (silc_unlikely(ret == -1))
506 if (silc_unlikely((message->data_len > silc_buffer_len(&buffer) -
507 6 - mac_len - iv_len) ||
508 (message->pad_len + message->data_len >
509 silc_buffer_len(&buffer) - 6 - mac_len - iv_len))) {
510 SILC_LOG_ERROR(("Incorrect Message Payload in packet"));
514 /* Parse Signed Message Payload if provided */
515 if (message->flags & SILC_MESSAGE_FLAG_SIGNED &&
516 message->data_len + message->pad_len + 6 + mac_len +
517 iv_len < silc_buffer_len(&buffer)) {
518 if (!silc_message_signed_payload_parse(buffer.data + 6 +
521 silc_buffer_len(&buffer) -
522 iv_len - mac_len - 6 -
529 /* Parse MAC from the payload */
531 message->mac = buffer.data + (silc_buffer_len(&buffer) - mac_len);
537 silc_message_payload_free(newp);
542 /***************************** Payload encoding *****************************/
544 /* This function is used to encrypt the Messsage Payload which is
545 the `data' and `data_len'. This is used internally by the Message
546 Payload encoding routines but application may call this too if needed.
547 The `true_len' is the data length which is used to create MAC out of. */
549 SilcBool silc_message_payload_encrypt(unsigned char *data,
558 unsigned char sid[32], rid[32];
559 SilcUInt32 sid_len = 0, rid_len = 0;
561 /* Encrypt payload of the packet */
562 if (silc_unlikely(!silc_cipher_encrypt(cipher, data, data, data_len, iv)))
566 silc_id_id2str(&sender_id->u.client_id, SILC_ID_CLIENT, sid, sizeof(sid),
568 if (receiver_id->type == SILC_ID_CLIENT)
569 silc_id_id2str(&receiver_id->u.client_id, SILC_ID_CLIENT, rid,
570 sizeof(rid), &rid_len);
571 else if (receiver_id->type == SILC_ID_CHANNEL)
572 silc_id_id2str(&receiver_id->u.channel_id, SILC_ID_CHANNEL, rid,
573 sizeof(rid), &rid_len);
575 /* Compute the MAC of the encrypted message data */
576 silc_hmac_init(hmac);
577 silc_hmac_update(hmac, data, true_len);
578 silc_hmac_update(hmac, sid, sid_len);
579 silc_hmac_update(hmac, rid, rid_len);
580 silc_hmac_final(hmac, data + true_len, NULL);
585 /* Encrypt message payload */
587 static int silc_message_payload_encode_encrypt(SilcStack stack,
589 void *value, void *context)
591 SilcMessageEncode *e = context;
594 if (!e->cipher || !e->hmac)
597 mac_len = silc_hmac_len(e->hmac);
598 if (silc_unlikely(!silc_buffer_enlarge(buffer, mac_len)))
601 if (silc_unlikely(!silc_message_payload_encrypt(buffer->head,
603 silc_buffer_headlen(buffer),
604 e->iv, &e->sid, &e->rid,
605 e->cipher, e->hmac)))
611 /* Finalize message payload encoding */
614 silc_message_payload_encode_final(SilcBuffer buffer,
615 SilcMessageFlags flags,
620 SilcUInt32 payload_len,
624 SilcBuffer signature,
625 SilcMessagePayloadEncoded encoded,
634 e.rid = *receiver_id;
636 e.payload_len = payload_len;
639 if (silc_buffer_format(buffer,
640 SILC_STR_DATA(signature ?
641 silc_buffer_data(signature) : NULL,
643 silc_buffer_len(signature) : 0),
644 SILC_STR_DATA(iv, iv_len),
645 SILC_STR_FUNC(silc_message_payload_encode_encrypt,
648 silc_buffer_sfree(stack, buffer);
649 encoded(NULL, context);
653 /* Deliver message payload */
654 silc_buffer_start(buffer);
655 encoded(buffer, context);
657 silc_buffer_sfree(stack, buffer);
658 silc_buffer_sfree(stack, signature);
659 silc_stack_free(stack);
662 /* Encodes Message Payload into a buffer and returns it. */
665 silc_message_payload_encode(SilcMessageFlags flags,
666 const unsigned char *data,
668 SilcBool generate_iv,
669 SilcBool private_message,
673 SilcPublicKey public_key,
674 SilcPrivateKey private_key,
679 SilcMessagePayloadEncoded encoded,
682 SilcUInt32 pad_len = 0, mac_len = 0, iv_len = 0;
683 unsigned char pad[16], iv[SILC_CIPHER_MAX_IV_SIZE];
687 SILC_LOG_DEBUG(("Encoding Message Payload"));
689 if (silc_unlikely(!data_len)) {
690 encoded(NULL, context);
693 if (silc_unlikely(!private_message && (!cipher || !hmac))) {
694 encoded(NULL, context);
698 stack = silc_stack_alloc(0, stack ? stack : silc_crypto_stack());
700 buffer = silc_buffer_salloc(stack, 0);
701 if (silc_unlikely(!buffer)) {
702 encoded(NULL, context);
703 silc_stack_free(stack);
707 /* For channel messages IV is always generated */
708 if (!private_message && !generate_iv)
712 if (cipher && generate_iv) {
713 iv_len = silc_cipher_get_block_len(cipher);
715 for (i = 0; i < iv_len; i++) iv[i] = silc_rng_get_byte_fast(rng);
717 for (i = 0; i < iv_len; i++) iv[i] = silc_rng_global_get_byte_fast();
722 mac_len = silc_hmac_len(hmac);
723 data_len = silc_message_payload_datalen(data_len, mac_len + iv_len, flags,
724 public_key, private_key);
726 /* Calculate length of padding. IV is not included into the calculation
727 since it is not encrypted. */
728 pad_len = SILC_MESSAGE_PAD(6 + data_len);
730 /* Generate padding */
733 for (i = 0; i < pad_len; i++) pad[i] = silc_rng_get_byte_fast(rng);
735 for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte_fast();
739 /* Encode the Message Payload */
740 if (silc_buffer_format(buffer,
742 SILC_STR_UI_SHORT(flags),
743 SILC_STR_UI_SHORT(data_len),
744 SILC_STR_DATA(data, data_len),
745 SILC_STR_UI_SHORT(pad_len),
746 SILC_STR_DATA(pad, pad_len),
748 silc_buffer_sfree(stack, buffer);
749 encoded(NULL, context);
750 silc_stack_free(stack);
754 if (flags & SILC_MESSAGE_FLAG_SIGNED) {
755 SilcMessageEncode *e = silc_scalloc(stack, 1, sizeof(*e));
757 silc_buffer_sfree(stack, buffer);
758 encoded(NULL, context);
759 silc_stack_free(stack);
766 e->public_key = public_key;
767 e->private_key = private_key;
773 e->rid = *receiver_id;
774 e->iv = iv_len ? iv : NULL;
776 e->payload_len = 6 + data_len + pad_len;
777 e->encoded = encoded;
778 e->context = context;
780 /* Compute signature */
781 return silc_message_signed_payload_encode(buffer, e);
785 silc_message_payload_encode_final(buffer, flags, cipher, hmac,
786 iv_len ? iv : NULL, iv_len,
787 6 + data_len + pad_len,
788 sender_id, receiver_id, stack, NULL,
793 /* Free's Message Payload */
795 void silc_message_payload_free(SilcMessagePayload payload)
797 silc_message_signed_payload_free(&payload->sig);
799 memset(payload->data, 0, payload->data_len);
800 if (payload->allocated)
801 silc_free(payload->data);
803 if (payload->allocated) {
804 silc_free(payload->pad);
811 SilcMessageFlags silc_message_get_flags(SilcMessagePayload payload)
813 return payload->flags;
818 unsigned char *silc_message_get_data(SilcMessagePayload payload,
819 SilcUInt32 *data_len)
822 *data_len = payload->data_len;
823 return payload->data;
826 /* Return MAC. The caller knows the length of the MAC */
828 unsigned char *silc_message_get_mac(SilcMessagePayload payload)
833 /* Verify the signature in SILC_MESSAGE_FLAG_SIGNED Payload */
836 silc_message_signed_verify(SilcMessagePayload message,
837 SilcPublicKey remote_public_key,
839 SilcAuthResultCb result,
842 SilcAsyncOperation op;
843 SilcBuffer sign, tmp;
844 SilcStack stack = NULL;
845 SilcMessageSignedPayload sig = &message->sig;
847 if (!(message->flags & SILC_MESSAGE_FLAG_SIGNED) ||
848 !sig->sign_len || !remote_public_key || !hash) {
849 result(FALSE, context);
853 if (silc_crypto_stack())
854 stack = silc_stack_alloc(0, silc_crypto_stack());
856 /* Generate the signature verification data, the Message Payload */
857 tmp = silc_buffer_salloc_size(stack,
858 6 + message->data_len + message->pad_len);
859 silc_buffer_sformat(stack, tmp,
860 SILC_STR_UI_SHORT(message->flags),
861 SILC_STR_UI_SHORT(message->data_len),
862 SILC_STR_DATA(message->data, message->data_len),
863 SILC_STR_UI_SHORT(message->pad_len),
864 SILC_STR_DATA(message->pad, message->pad_len),
866 sign = silc_message_signed_encode_data(stack, tmp->data, silc_buffer_len(tmp),
867 sig->pk_data, sig->pk_len,
869 silc_buffer_clear(tmp);
870 silc_buffer_sfree(stack, tmp);
873 result(FALSE, context);
874 silc_stack_free(stack);
878 /* Verify the authentication data */
879 op = silc_pkcs_verify(remote_public_key, sig->sign_data, sig->sign_len,
880 silc_buffer_data(sign), silc_buffer_len(sign),
881 hash, result, context);
883 silc_buffer_clear(sign);
884 silc_buffer_sfree(stack, sign);
885 silc_stack_free(stack);
890 /* Return the public key from the payload */
893 silc_message_signed_get_public_key(SilcMessagePayload payload,
894 const unsigned char **pk_data,
895 SilcUInt32 *pk_data_len)
898 SilcMessageSignedPayload sig = &payload->sig;
903 if (!silc_pkcs_public_key_alloc(sig->pk_type, sig->pk_data,
908 *pk_data = sig->pk_data;
910 *pk_data_len = sig->pk_len;