5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2014 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 */
39 SilcMessageFlags flags;
40 SilcPublicKey public_key;
41 SilcPrivateKey private_key;
46 SilcUInt16 payload_len;
52 /************************* Static utility functions *************************/
54 /* Returns the data length that fits to the packet. If data length is too
55 big it will be truncated to fit to the payload. */
58 SilcUInt32 silc_message_payload_datalen(SilcUInt32 data_len,
59 SilcUInt32 header_len,
61 SilcPublicKey public_key,
62 SilcPrivateKey private_key)
64 SilcUInt32 pklen = (flags & SILC_MESSAGE_FLAG_SIGNED && public_key ?
65 silc_pkcs_public_key_get_len(public_key) : 0);
66 SilcUInt32 prlen = (flags & SILC_MESSAGE_FLAG_SIGNED ?
67 silc_pkcs_private_key_get_len(private_key) / 8 : 0);
68 SilcUInt32 dlen = data_len + SILC_MESSAGE_HLEN + header_len + pklen + prlen;
70 if (silc_unlikely(dlen > SILC_MESSAGE_MAX_LEN))
71 data_len -= (dlen - SILC_MESSAGE_MAX_LEN);
76 /* Free signed payload */
78 static void silc_message_signed_payload_free(SilcMessageSignedPayload sig)
81 memset(sig->sign_data, 0, sig->sign_len);
82 silc_free(sig->sign_data);
84 silc_free(sig->pk_data);
87 /* Parses the SILC_MESSAGE_FLAG_SIGNED Payload */
90 silc_message_signed_payload_parse(const unsigned char *data,
92 SilcMessageSignedPayload sig)
94 SilcBufferStruct buffer;
97 SILC_LOG_DEBUG(("Parsing SILC_MESSAGE_FLAG_SIGNED Payload"));
99 SILC_LOG_HEXDUMP(("sig payload"), (unsigned char *)data, data_len);
101 silc_buffer_set(&buffer, (unsigned char *)data, data_len);
103 /* Parse the payload */
104 ret = silc_buffer_unformat(&buffer,
105 SILC_STR_UI_SHORT(&sig->pk_len),
106 SILC_STR_UI_SHORT(&sig->pk_type),
108 if (ret == -1 || sig->pk_len > data_len - 4) {
109 SILC_LOG_DEBUG(("Malformed public key in SILC_MESSAGE_FLAG_SIGNED "
114 silc_buffer_pull(&buffer, 4);
115 ret = silc_buffer_unformat(&buffer,
116 SILC_STR_UI_XNSTRING_ALLOC(&sig->pk_data,
118 SILC_STR_UI16_NSTRING_ALLOC(&sig->sign_data,
121 if (ret == -1 || sig->sign_len > silc_buffer_len(&buffer) -
123 silc_message_signed_payload_free(sig);
124 SILC_LOG_DEBUG(("Malformed SILC_MESSAGE_FLAG_SIGNED Payload"));
127 silc_buffer_push(&buffer, 4);
129 /* Signature must be provided */
130 if (sig->sign_len < 1) {
131 SILC_LOG_DEBUG(("Malformed signature in SILC_MESSAGE_SIGNED_PAYLOAD "
133 silc_message_signed_payload_free(sig);
140 /* Encodes the data to be signed to SILC_MESSAGE_FLAG_SIGNED Payload */
143 silc_message_signed_encode_data(const unsigned char *message_payload,
144 SilcUInt32 message_payload_len,
146 SilcUInt32 pk_len, SilcUInt32 pk_type)
150 sign = silc_buffer_alloc_size(message_payload_len + 4 + pk_len);
154 silc_buffer_format(sign,
155 SILC_STR_UI_XNSTRING(message_payload,
156 message_payload_len),
157 SILC_STR_UI_SHORT(pk_len),
158 SILC_STR_UI_SHORT(pk_type),
162 silc_buffer_pull(sign, message_payload_len + 4);
163 silc_buffer_format(sign,
164 SILC_STR_UI_XNSTRING(pk, pk_len),
166 silc_buffer_push(sign, message_payload_len + 4);
172 /* Encodes the SILC_MESSAGE_FLAG_SIGNED Payload and computes the digital
176 silc_message_signed_payload_encode(const unsigned char *message_payload,
177 SilcUInt32 message_payload_len,
178 SilcPublicKey public_key,
179 SilcPrivateKey private_key,
182 SilcBuffer buffer, sign;
183 unsigned char auth_data[65536 + 1];
185 unsigned char *pk = NULL;
186 SilcUInt32 pk_len = 0;
189 if (!message_payload || !message_payload_len || !private_key || !hash)
193 pk = silc_pkcs_public_key_encode(public_key, &pk_len);
197 pk_type = silc_pkcs_get_type(private_key);
199 /* Encode the data to be signed */
200 sign = silc_message_signed_encode_data(message_payload,
202 pk, pk_len, pk_type);
208 /* Sign the buffer */
210 /* Compute the hash and the signature. */
211 if (!silc_pkcs_sign(private_key, sign->data, silc_buffer_len(sign),
212 auth_data, sizeof(auth_data) - 1, &auth_len,
214 SILC_LOG_ERROR(("Could not compute signature"));
215 silc_buffer_clear(sign);
216 silc_buffer_free(sign);
221 /* Encode the SILC_MESSAGE_FLAG_SIGNED Payload */
223 buffer = silc_buffer_alloc_size(4 + pk_len + 2 + auth_len);
225 silc_buffer_clear(sign);
226 silc_buffer_free(sign);
227 memset(auth_data, 0, sizeof(auth_data));
232 silc_buffer_format(buffer,
233 SILC_STR_UI_SHORT(pk_len),
234 SILC_STR_UI_SHORT(pk_type),
238 silc_buffer_pull(buffer, 4);
239 silc_buffer_format(buffer,
240 SILC_STR_UI_XNSTRING(pk, pk_len),
242 silc_buffer_push(buffer, 4);
245 silc_buffer_pull(buffer, 4 + pk_len);
246 silc_buffer_format(buffer,
247 SILC_STR_UI_SHORT(auth_len),
248 SILC_STR_UI_XNSTRING(auth_data, auth_len),
250 silc_buffer_push(buffer, 4 + pk_len);
252 SILC_LOG_HEXDUMP(("sig payload"), buffer->data, silc_buffer_len(buffer));
254 memset(auth_data, 0, sizeof(auth_data));
255 silc_buffer_clear(sign);
256 silc_buffer_free(sign);
263 /***************************** Payload parsing ******************************/
265 /* Decrypts the Message Payload. The `data' is the actual Message Payload. */
267 SilcBool silc_message_payload_decrypt(unsigned char *data,
269 SilcBool private_message,
273 unsigned char *sender_id,
274 SilcUInt32 sender_id_len,
275 unsigned char *receiver_id,
276 SilcUInt32 receiver_id_len,
279 SilcUInt32 mac_len, iv_len = 0, block_len;
280 SilcUInt16 len, totlen;
281 unsigned char mac[32], *ivp;
283 mac_len = silc_hmac_len(hmac);
284 block_len = silc_cipher_get_block_len(cipher);
286 /* IV is present for all channel messages, and private messages when
287 static key (pre-shared key) is used. */
288 if (!private_message || (private_message && static_key))
291 if (silc_unlikely(data_len < (mac_len + iv_len + block_len)))
294 if (silc_likely(check_mac)) {
295 /* Check the MAC of the message */
296 SILC_LOG_DEBUG(("Checking message MAC"));
297 silc_hmac_init(hmac);
298 silc_hmac_update(hmac, data, data_len - mac_len);
299 silc_hmac_update(hmac, sender_id, sender_id_len);
300 silc_hmac_update(hmac, receiver_id, receiver_id_len);
301 silc_hmac_final(hmac, mac, &mac_len);
302 if (silc_unlikely(memcmp(data + (data_len - mac_len), mac, mac_len))) {
303 #if 1 /* Check for old style message MAC. Remove this check at some point. */
304 silc_hmac_init(hmac);
305 silc_hmac_update(hmac, data, data_len - mac_len);
306 silc_hmac_final(hmac, mac, &mac_len);
307 if (silc_unlikely(memcmp(data + (data_len - mac_len), mac, mac_len))) {
308 SILC_LOG_DEBUG(("Message MAC does not match"));
312 SILC_LOG_DEBUG(("Message MAC does not match"));
316 SILC_LOG_DEBUG(("MAC is Ok"));
319 /* Decrypt first only one block to get the header and then rest of
320 the data. This is done because there might be unencrypted data at
321 the end and we don't know the encrypted length yet. */
323 /* Get pointer to the IV */
324 ivp = (iv_len ? data + (data_len - iv_len - mac_len) :
325 silc_cipher_get_iv(cipher));
328 if (silc_unlikely(!silc_cipher_decrypt(cipher, data, data, block_len,
334 /* Get the payload length and decrypt rest */
336 SILC_GET16_MSB(len, data + totlen);
338 if (silc_unlikely(totlen + iv_len + mac_len + 2 > data_len))
341 if (totlen >= block_len)
342 if (silc_unlikely(!silc_cipher_decrypt(cipher, data + block_len,
344 (totlen - block_len) +
345 SILC_MESSAGE_PAD(totlen), ivp))) {
353 /* Parses Message Payload returning new payload structure. This also
354 decrypts it and checks the MAC. */
357 silc_message_payload_parse(unsigned char *payload,
358 SilcUInt32 payload_len,
359 SilcBool private_message,
363 unsigned char *sender_id,
364 SilcUInt32 sender_id_len,
365 unsigned char *receiver_id,
366 SilcUInt32 receiver_id_len,
368 SilcBool no_allocation,
369 SilcMessagePayload message)
371 SilcBufferStruct buffer;
372 SilcMessagePayload newp = NULL;
374 SilcUInt32 mac_len = 0, iv_len = 0;
376 SILC_LOG_DEBUG(("Parsing Message Payload"));
378 silc_buffer_set(&buffer, payload, payload_len);
380 /* Decrypt the payload */
381 if (silc_likely(cipher)) {
382 ret = silc_message_payload_decrypt(buffer.data, silc_buffer_len(&buffer),
383 private_message, static_key,
384 cipher, hmac, sender_id,
385 sender_id_len, receiver_id,
386 receiver_id_len, TRUE);
387 if (silc_unlikely(ret == FALSE))
391 if (silc_likely(hmac))
392 mac_len = silc_hmac_len(hmac);
394 /* IV is present for all channel messages, and private messages when
395 static key (pre-shared key) is used. */
396 if (cipher && (!private_message || (private_message && static_key)))
397 iv_len = silc_cipher_get_block_len(cipher);
400 newp = message = silc_calloc(1, sizeof(*newp));
401 if (silc_unlikely(!newp))
404 memset(message, 0, sizeof(*message));
405 message->allocated = (stack || no_allocation ? FALSE : TRUE);
407 /* Parse the Message Payload. */
409 ret = silc_buffer_sunformat(stack, &buffer,
410 SILC_STR_UI_SHORT(&message->flags),
411 SILC_STR_UI16_NSTRING_ALLOC(&message->data,
413 SILC_STR_UI16_NSTRING_ALLOC(&message->pad,
417 ret = silc_buffer_unformat(&buffer,
418 SILC_STR_UI_SHORT(&message->flags),
419 SILC_STR_UI16_NSTRING(&message->data,
421 SILC_STR_UI16_NSTRING(&message->pad,
424 if (silc_unlikely(ret == -1))
427 if (silc_unlikely((message->data_len > silc_buffer_len(&buffer) -
428 6 - mac_len - iv_len) ||
429 (message->pad_len + message->data_len >
430 silc_buffer_len(&buffer) - 6 - mac_len - iv_len))) {
431 SILC_LOG_ERROR(("Incorrect Message Payload in packet"));
435 /* Parse Signed Message Payload if provided */
436 if (message->flags & SILC_MESSAGE_FLAG_SIGNED &&
437 message->data_len + message->pad_len + 6 + mac_len +
438 iv_len < silc_buffer_len(&buffer)) {
439 if (!silc_message_signed_payload_parse(buffer.data + 6 +
442 silc_buffer_len(&buffer) -
443 iv_len - mac_len - 6 -
450 /* Parse MAC from the payload */
452 message->mac = buffer.data + (silc_buffer_len(&buffer) - mac_len);
458 silc_message_payload_free(newp);
463 /***************************** Payload encoding *****************************/
465 /* This function is used to encrypt the Messsage Payload which is
466 the `data' and `data_len'. This is used internally by the Message
467 Payload encoding routines but application may call this too if needed.
468 The `true_len' is the data length which is used to create MAC out of. */
470 SilcBool silc_message_payload_encrypt(unsigned char *data,
479 unsigned char sid[32], rid[32];
480 SilcUInt32 sid_len = 0, rid_len = 0;
482 /* Encrypt payload of the packet */
483 if (silc_unlikely(!silc_cipher_encrypt(cipher, data, data, data_len, iv)))
487 silc_id_id2str(&sender_id->u.client_id, SILC_ID_CLIENT, sid, sizeof(sid),
489 if (receiver_id->type == SILC_ID_CLIENT)
490 silc_id_id2str(&receiver_id->u.client_id, SILC_ID_CLIENT, rid,
491 sizeof(rid), &rid_len);
492 else if (receiver_id->type == SILC_ID_CHANNEL)
493 silc_id_id2str(&receiver_id->u.channel_id, SILC_ID_CHANNEL, rid,
494 sizeof(rid), &rid_len);
496 /* Compute the MAC of the encrypted message data */
497 silc_hmac_init(hmac);
498 silc_hmac_update(hmac, data, true_len);
499 silc_hmac_update(hmac, sid, sid_len);
500 silc_hmac_update(hmac, rid, rid_len);
501 silc_hmac_final(hmac, data + true_len, NULL);
506 /* Encrypt message payload */
508 static int silc_message_payload_encode_encrypt(SilcBuffer buffer,
509 void *value, void *context)
511 SilcMessageEncode *e = context;
514 if (!e->cipher || !e->hmac)
517 mac_len = silc_hmac_len(e->hmac);
518 if (silc_unlikely(!silc_buffer_enlarge(buffer, mac_len)))
521 if (silc_unlikely(!silc_message_payload_encrypt(buffer->head,
523 silc_buffer_headlen(buffer),
524 e->iv, e->sid, e->rid,
525 e->cipher, e->hmac)))
531 /* Compute message signature */
533 static int silc_message_payload_encode_sig(SilcBuffer buffer,
534 void *value, void *context)
536 SilcMessageEncode *e = context;
540 if (!(e->flags & SILC_MESSAGE_FLAG_SIGNED))
543 sig = silc_message_signed_payload_encode(buffer->head,
544 silc_buffer_headlen(buffer),
545 e->public_key, e->private_key,
547 if (silc_unlikely(!sig))
550 len = silc_buffer_format(buffer,
551 SILC_STR_DATA(silc_buffer_data(sig),
552 silc_buffer_len(sig)),
554 if (silc_unlikely(len < 0)) {
555 silc_buffer_free(sig);
559 silc_buffer_free(sig);
563 /* Encodes Message Payload into a buffer and returns it. */
565 SilcBuffer silc_message_payload_encode(SilcMessageFlags flags,
566 const unsigned char *data,
568 SilcBool generate_iv,
569 SilcBool private_message,
573 SilcPublicKey public_key,
574 SilcPrivateKey private_key,
580 SilcUInt32 pad_len = 0, mac_len = 0, iv_len = 0;
581 unsigned char pad[16], iv[SILC_CIPHER_MAX_IV_SIZE];
582 SilcBuffer buf = NULL;
586 SILC_LOG_DEBUG(("Encoding Message Payload"));
588 if (silc_unlikely(!data_len))
590 if (silc_unlikely(!private_message && (!cipher || !hmac)))
594 buf = buffer = silc_buffer_alloc(0);
595 if (silc_unlikely(!buf))
598 silc_buffer_reset(buffer);
600 /* For channel messages IV is always generated */
601 if (!private_message && !generate_iv)
605 if (cipher && generate_iv) {
606 iv_len = silc_cipher_get_block_len(cipher);
608 for (i = 0; i < iv_len; i++) iv[i] = silc_rng_get_byte_fast(rng);
610 for (i = 0; i < iv_len; i++) iv[i] = silc_rng_global_get_byte_fast();
615 mac_len = silc_hmac_len(hmac);
616 data_len = silc_message_payload_datalen(data_len, mac_len + iv_len, flags,
617 public_key, private_key);
619 /* Calculate length of padding. IV is not included into the calculation
620 since it is not encrypted. */
621 pad_len = SILC_MESSAGE_PAD(6 + data_len);
623 /* Generate padding */
626 for (i = 0; i < pad_len; i++) pad[i] = silc_rng_get_byte_fast(rng);
628 for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte_fast();
633 e.public_key = public_key;
634 e.private_key = private_key;
640 e.iv = iv_len ? iv : NULL;
641 e.payload_len = 6 + data_len + pad_len;
643 /* Encode the Message Payload */
644 if (silc_buffer_format(buffer,
645 SILC_STR_UI_SHORT(flags),
646 SILC_STR_UI_SHORT(data_len),
647 SILC_STR_DATA(data, data_len),
648 SILC_STR_UI_SHORT(pad_len),
649 SILC_STR_DATA(pad, pad_len),
650 SILC_STR_FUNC(silc_message_payload_encode_sig,
652 SILC_STR_DATA(iv, iv_len),
653 SILC_STR_FUNC(silc_message_payload_encode_encrypt,
656 silc_buffer_free(buf);
663 /* Free's Message Payload */
665 void silc_message_payload_free(SilcMessagePayload payload)
667 silc_message_signed_payload_free(&payload->sig);
669 memset(payload->data, 0, payload->data_len);
670 if (payload->allocated)
671 silc_free(payload->data);
673 if (payload->allocated) {
674 silc_free(payload->pad);
681 SilcMessageFlags silc_message_get_flags(SilcMessagePayload payload)
683 return payload->flags;
688 unsigned char *silc_message_get_data(SilcMessagePayload payload,
689 SilcUInt32 *data_len)
692 *data_len = payload->data_len;
693 return payload->data;
696 /* Return MAC. The caller knows the length of the MAC */
698 unsigned char *silc_message_get_mac(SilcMessagePayload payload)
703 /* Verify the signature in SILC_MESSAGE_FLAG_SIGNED Payload */
705 SilcAuthResult silc_message_signed_verify(SilcMessagePayload message,
706 SilcPublicKey remote_public_key,
709 int ret = SILC_AUTH_FAILED;
710 SilcBuffer sign, tmp;
711 SilcMessageSignedPayload sig = &message->sig;
713 if (!(message->flags & SILC_MESSAGE_FLAG_SIGNED) ||
714 !sig->sign_len || !remote_public_key || !hash)
717 /* Generate the signature verification data, the Message Payload */
718 tmp = silc_buffer_alloc_size(6 + message->data_len + message->pad_len);
719 silc_buffer_format(tmp,
720 SILC_STR_UI_SHORT(message->flags),
721 SILC_STR_UI_SHORT(message->data_len),
722 SILC_STR_UI_XNSTRING(message->data, message->data_len),
723 SILC_STR_UI_SHORT(message->pad_len),
724 SILC_STR_UI_XNSTRING(message->pad, message->pad_len),
726 sign = silc_message_signed_encode_data(tmp->data, silc_buffer_len(tmp),
727 sig->pk_data, sig->pk_len,
729 silc_buffer_clear(tmp);
730 silc_buffer_free(tmp);
735 /* Verify the authentication data */
736 if (!silc_pkcs_verify(remote_public_key, sig->sign_data, sig->sign_len,
737 silc_buffer_data(sign), silc_buffer_len(sign), hash)) {
738 silc_buffer_clear(sign);
739 silc_buffer_free(sign);
740 SILC_LOG_DEBUG(("Signature verification failed"));
746 silc_buffer_clear(sign);
747 silc_buffer_free(sign);
749 SILC_LOG_DEBUG(("Signature verification successful"));
754 /* Return the public key from the payload */
757 silc_message_signed_get_public_key(SilcMessagePayload payload,
758 const unsigned char **pk_data,
759 SilcUInt32 *pk_data_len)
762 SilcMessageSignedPayload sig = &payload->sig;
767 if (!silc_pkcs_public_key_alloc(sig->pk_type, sig->pk_data,
772 *pk_data = sig->pk_data;
774 *pk_data_len = sig->pk_len;