5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2001 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.
20 * Created: Fri Jul 25 18:52:14 1997
24 #include "silcincludes.h"
26 /******************************************************************************
28 Packet Sending Routines
30 ******************************************************************************/
32 /* Actually sends the packet. This flushes the connections outgoing data
33 buffer. If data is sent directly to the network this returns the bytes
34 written, if error occured this returns -1 and if the data could not
35 be written directly to the network at this time this returns -2, in
36 which case the data should be queued by the caller and sent at some
37 later time. If `force_send' is TRUE this attempts to write the data
38 directly to the network, if FALSE, this returns -2. */
40 int silc_packet_send(SilcSocketConnection sock, bool force_send)
42 SILC_LOG_DEBUG(("Sending packet to %s:%d [%s]", sock->hostname,
44 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
45 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
46 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
49 /* Send now if forced to do so */
50 if (force_send == TRUE) {
53 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
55 /* Write to network */
56 ret = silc_socket_write(sock);
59 SILC_LOG_ERROR(("Error sending packet, dropped"));
64 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
67 SILC_LOG_DEBUG(("Packet in queue"));
72 /* Encrypts a packet. This also creates HMAC of the packet before
73 encryption and adds the HMAC at the end of the buffer. This assumes
74 that there is enough free space at the end of the buffer to add the
75 computed HMAC. This is the normal way of encrypting packets, if some
76 other process of HMAC computing and encryption is needed this function
79 void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac,
80 SilcBuffer buffer, uint32 len)
82 unsigned char mac[32];
85 /* Compute HMAC. This assumes that HMAC is created from the entire
86 data area thus this uses the length found in buffer, not the length
90 silc_hmac_update(hmac, buffer->data, buffer->len);
91 silc_hmac_final(hmac, mac, &mac_len);
92 silc_buffer_put_tail(buffer, mac, mac_len);
93 memset(mac, 0, sizeof(mac));
96 /* Encrypt the data area of the packet. 2 bytes of the packet
99 SILC_LOG_DEBUG(("Encrypting packet, cipher %s, len %d (%d)",
100 cipher->cipher->name, len, len - 2));
101 cipher->cipher->encrypt(cipher->context, buffer->data + 2,
102 buffer->data + 2, len - 2, cipher->iv);
105 /* Pull the HMAC into the visible data area in the buffer */
107 silc_buffer_pull_tail(buffer, mac_len);
110 /* Assembles a new packet to be ready for send out. The buffer sent as
111 argument must include the data to be sent and it must not be encrypted.
112 The packet also must have enough free space so that the SILC header
113 and padding maybe added to the packet. The packet is encrypted after
114 this function has returned.
116 The buffer sent as argument should be something like following:
118 --------------------------------------------
119 | head | data | tail |
120 --------------------------------------------
124 So that the SILC header and 1 - 16 bytes of padding can fit to
125 the buffer. After assembly the buffer might look like this:
127 --------------------------------------------
129 --------------------------------------------
131 Start of assembled packet
133 Packet construct is as follows (* = won't be encrypted):
136 2 bytes Payload length (*)
139 2 bytes Source ID Length
140 2 bytes Destination ID Length
141 1 byte Source ID Type
143 1 byte Destination ID Type
144 n bytes Destination ID
150 All fields in the packet will be authenticated by MAC. The MAC is
151 not computed here, it must be computed separately before encrypting
156 void silc_packet_assemble(SilcPacketContext *ctx)
158 unsigned char tmppad[SILC_PACKET_MAX_PADLEN];
161 SILC_LOG_DEBUG(("Assembling outgoing packet"));
163 /* Get the true length of the packet. This is saved as payload length
164 into the packet header. This does not include the length of the
167 ctx->truelen = ctx->buffer->len + SILC_PACKET_HEADER_LEN +
168 ctx->src_id_len + ctx->dst_id_len;
170 /* Calculate the length of the padding. The padding is calculated from
171 the data that will be encrypted. As protocol states 3 first bytes
172 of the packet are not encrypted they are not included in the
173 padding calculation. */
175 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
177 /* Put the start of the data section to the right place. */
178 silc_buffer_push(ctx->buffer, SILC_PACKET_HEADER_LEN +
179 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
181 /* Get random padding */
183 for (i = 0; i < ctx->padlen; i++) tmppad[i] = silc_rng_global_get_byte();
185 /* XXX: For testing - to be removed */
186 memset(tmppad, 65, sizeof(tmppad));
189 /* Create the packet. This creates the SILC header and adds padding,
190 rest of the buffer remains as it is. */
191 silc_buffer_format(ctx->buffer,
192 SILC_STR_UI_SHORT(ctx->truelen),
193 SILC_STR_UI_CHAR(ctx->flags),
194 SILC_STR_UI_CHAR(ctx->type),
195 SILC_STR_UI_SHORT(ctx->src_id_len),
196 SILC_STR_UI_SHORT(ctx->dst_id_len),
197 SILC_STR_UI_CHAR(ctx->src_id_type),
198 SILC_STR_UI_XNSTRING(ctx->src_id, ctx->src_id_len),
199 SILC_STR_UI_CHAR(ctx->dst_id_type),
200 SILC_STR_UI_XNSTRING(ctx->dst_id, ctx->dst_id_len),
201 SILC_STR_UI_XNSTRING(tmppad, ctx->padlen),
204 SILC_LOG_HEXDUMP(("Assembled packet, len %d", ctx->buffer->len),
205 ctx->buffer->data, ctx->buffer->len);
207 SILC_LOG_DEBUG(("Outgoing packet assembled"));
210 /* Prepare outgoing data buffer for packet sending. This moves the data
211 area so that new packet may be added into it. If needed this allocates
212 more space to the buffer. This handles directly the connection's
213 outgoing buffer in SilcSocketConnection object. */
215 void silc_packet_send_prepare(SilcSocketConnection sock,
222 totlen = header_len + padlen + data_len;
224 /* Prepare the outgoing buffer for packet sending. */
226 /* Allocate new buffer. This is done only once per connection. */
227 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
229 if (totlen > SILC_PACKET_DEFAULT_SIZE)
230 sock->outbuf = silc_buffer_alloc(totlen);
232 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
233 silc_buffer_pull_tail(sock->outbuf, totlen);
234 silc_buffer_pull(sock->outbuf, header_len + padlen);
236 if (SILC_IS_OUTBUF_PENDING(sock)) {
237 /* There is some pending data in the buffer. */
239 /* Allocate more space if needed */
240 if ((sock->outbuf->end - sock->outbuf->tail) <
242 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
243 sock->outbuf = silc_buffer_realloc(sock->outbuf,
244 sock->outbuf->truelen +
248 oldlen = sock->outbuf->len;
249 silc_buffer_pull_tail(sock->outbuf, totlen);
250 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
252 /* Buffer is free for use */
253 silc_buffer_clear(sock->outbuf);
255 /* Allocate more space if needed */
256 if ((sock->outbuf->end - sock->outbuf->tail) < (totlen + 20)) {
257 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
258 sock->outbuf = silc_buffer_realloc(sock->outbuf,
259 sock->outbuf->truelen +
263 silc_buffer_pull_tail(sock->outbuf, totlen);
264 silc_buffer_pull(sock->outbuf, header_len + padlen);
269 /******************************************************************************
271 Packet Reception Routines
273 ******************************************************************************/
275 /* Processes the received data. This checks the received data and
276 calls parser callback that handles the actual packet decryption
277 and parsing. If more than one packet was received this calls the
278 parser multiple times. The parser callback will get context
279 SilcPacketParserContext that includes the packet and the `context'
280 sent to this function. */
282 void silc_packet_receive_process(SilcSocketConnection sock,
283 SilcCipher cipher, SilcHmac hmac,
284 SilcPacketParserCallback parser,
287 SilcPacketParserContext *parse_ctx;
288 int packetlen, paddedlen, count, mac_len = 0;
290 /* We need at least 2 bytes of data to be able to start processing
292 if (sock->inbuf->len < 2)
296 mac_len = silc_hmac_len(hmac);
298 /* Parse the packets from the data */
300 while (sock->inbuf->len > 0) {
301 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
305 if (packetlen < SILC_PACKET_MIN_LEN) {
306 SILC_LOG_DEBUG(("Received invalid packet, dropped"));
307 silc_buffer_clear(sock->inbuf);
311 if (sock->inbuf->len < paddedlen + mac_len) {
312 SILC_LOG_DEBUG(("Received partial packet, waiting for the rest"));
316 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
317 parse_ctx->packet = silc_packet_context_alloc();
318 parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len);
319 parse_ctx->sock = sock;
320 parse_ctx->context = context;
322 silc_buffer_pull_tail(parse_ctx->packet->buffer,
323 SILC_BUFFER_END(parse_ctx->packet->buffer));
324 silc_buffer_put(parse_ctx->packet->buffer, sock->inbuf->data,
325 paddedlen + mac_len);
327 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
328 parse_ctx->packet->buffer->len),
329 parse_ctx->packet->buffer->data,
330 parse_ctx->packet->buffer->len);
332 /* Call the parser */
334 (*parser)(parse_ctx);
336 /* Pull the packet from inbuf thus we'll get the next one
338 silc_buffer_pull(sock->inbuf, paddedlen);
340 silc_buffer_pull(sock->inbuf, mac_len);
343 SILC_LOG_DEBUG(("Clearing inbound buffer"));
344 silc_buffer_clear(sock->inbuf);
347 /* Receives packet from network and reads the data into connection's
348 incoming data buffer. If the data was read directly this returns the
349 read bytes, if error occured this returns -1, if the data could not
350 be read directly at this time this returns -2 in which case the data
351 should be read again at some later time, or If EOF occured this returns
354 int silc_packet_receive(SilcSocketConnection sock)
358 SILC_LOG_DEBUG(("Receiving packet from %s:%d [%s]", sock->hostname,
360 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
361 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
362 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
365 /* Read some data from connection */
366 ret = silc_socket_read(sock);
371 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
372 after packet has been totally decrypted and parsed. */
374 static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer)
378 unsigned char mac[32];
381 SILC_LOG_DEBUG(("Verifying MAC"));
383 /* Compute HMAC of packet */
384 memset(mac, 0, sizeof(mac));
385 silc_hmac_init(hmac);
386 silc_hmac_update(hmac, buffer->data, buffer->len);
387 silc_hmac_final(hmac, mac, &mac_len);
389 /* Compare the HMAC's (buffer->tail has the packet's HMAC) */
390 if (memcmp(mac, buffer->tail, mac_len)) {
391 SILC_LOG_ERROR(("MAC failed"));
395 SILC_LOG_DEBUG(("MAC is Ok"));
396 memset(mac, 0, sizeof(mac));
402 /* Decrypts rest of the packet (after decrypting just the SILC header).
403 After calling this function the packet is ready to be parsed by calling
404 silc_packet_parse. If everything goes without errors this returns TRUE,
405 if packet is malformed this returns FALSE. */
407 static int silc_packet_decrypt_rest(SilcCipher cipher, SilcHmac hmac,
412 /* Pull MAC from packet before decryption */
414 if ((buffer->len - silc_hmac_len(hmac)) > SILC_PACKET_MIN_LEN) {
415 silc_buffer_push_tail(buffer, silc_hmac_len(hmac));
417 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
422 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
424 /* Decrypt rest of the packet */
425 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
426 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
427 buffer->data + 2, buffer->len - 2,
429 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
431 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
432 buffer->data, buffer->len);
438 /* Decrypts rest of the SILC Packet header that has been decrypted partly
439 already. This decrypts the padding of the packet also. After calling
440 this function the packet is ready to be parsed by calling function
441 silc_packet_parse. This is used in special packet reception (protocol
442 defines the way of decrypting special packets). */
444 static int silc_packet_decrypt_rest_special(SilcCipher cipher,
448 /* Decrypt rest of the header plus padding */
450 uint16 truelen, len1, len2, padlen;
452 /* Pull MAC from packet before decryption */
454 if ((buffer->len - silc_hmac_len(hmac)) > SILC_PACKET_MIN_LEN) {
455 silc_buffer_push_tail(buffer, silc_hmac_len(hmac));
457 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
462 SILC_LOG_DEBUG(("Decrypting rest of the header"));
464 SILC_GET16_MSB(len1, &buffer->data[4]);
465 SILC_GET16_MSB(len2, &buffer->data[6]);
467 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
468 padlen = SILC_PACKET_PADLEN(truelen);
469 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
471 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
472 if (len1 - 2 > buffer->len) {
473 SILC_LOG_DEBUG(("Garbage in header of packet, bad packet length, "
478 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
479 buffer->data + 2, len1 - 2,
481 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
487 /* Decrypts a packet. This assumes that typical SILC packet is the
488 packet to be decrypted and thus checks for normal and special SILC
489 packets and can handle both of them. This also computes and checks
490 the HMAC of the packet. If any other special or customized decryption
491 processing is required this function cannot be used. This returns
492 -1 on error, 0 when packet is normal packet and 1 when the packet
493 is special and requires special processing.
495 The `check_packet' is a callback funtion that this function will
496 call. The callback relates to the checking whether the packet is
497 normal packet or special packet and how it should be processed. If
498 the callback return TRUE the packet is normal and FALSE if the packet
499 is special and requires special procesing. */
501 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
502 SilcBuffer buffer, SilcPacketContext *packet,
503 SilcPacketCheckDecrypt check_packet,
508 /* Decrypt start of the packet header */
510 silc_cipher_decrypt(cipher, buffer->data + 2, buffer->data + 2,
511 SILC_PACKET_MIN_HEADER_LEN - 2, cipher->iv);
513 /* Do packet checking, whether the packet is normal or special */
514 check = check_packet((SilcPacketType)buffer->data[3], buffer,
517 /* If the packet type is not any special type lets decrypt rest
518 of the packet here. */
520 /* Normal packet, decrypt rest of the packet */
521 if (!silc_packet_decrypt_rest(cipher, hmac, buffer))
525 if (!silc_packet_check_mac(hmac, buffer))
530 /* Packet requires special handling, decrypt rest of the header.
531 This only decrypts. */
532 if (!silc_packet_decrypt_rest_special(cipher, hmac, buffer))
536 if (!silc_packet_check_mac(hmac, buffer))
543 /* Parses the packet. This is called when a whole packet is ready to be
544 parsed. The buffer sent must be already decrypted before calling this
545 function. The len argument must be the true length of the packet. This
546 function returns the type of the packet. The data section of the
547 buffer is parsed, not head or tail sections. */
549 SilcPacketType silc_packet_parse(SilcPacketContext *ctx)
551 SilcBuffer buffer = ctx->buffer;
554 SILC_LOG_DEBUG(("Parsing incoming packet"));
556 /* Check the length of the buffer */
557 if (buffer->len < SILC_PACKET_MIN_LEN) {
558 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
559 return SILC_PACKET_NONE;
562 /* Parse the buffer. This parses the SILC header of the packet. */
563 len = silc_buffer_unformat(buffer,
564 SILC_STR_UI_SHORT(&ctx->truelen),
565 SILC_STR_UI_CHAR(&ctx->flags),
566 SILC_STR_UI_CHAR(&ctx->type),
567 SILC_STR_UI_SHORT(&ctx->src_id_len),
568 SILC_STR_UI_SHORT(&ctx->dst_id_len),
569 SILC_STR_UI_CHAR(&ctx->src_id_type),
572 return SILC_PACKET_NONE;
574 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
575 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
576 SILC_LOG_ERROR(("Bad ID lengths in packet"));
577 return SILC_PACKET_NONE;
580 /* Calculate length of padding in packet */
581 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
583 silc_buffer_pull(buffer, len);
584 ret = silc_buffer_unformat(buffer,
585 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
587 SILC_STR_UI_CHAR(&ctx->dst_id_type),
588 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
590 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
593 return SILC_PACKET_NONE;
595 silc_buffer_push(buffer, len);
597 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
598 ctx->buffer->data, ctx->buffer->len);
600 /* Pull SILC header and padding from packet */
601 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
602 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
604 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
609 /* Perform special SILC Packet header parsing. This is required to some
610 packet types that have the data payload encrypted with different key
611 than the header area plus padding of the packet. Hence, this parses
612 the header in a way that it does not take the data area into account
613 and parses the header and padding area only. */
615 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
617 SilcBuffer buffer = ctx->buffer;
618 int len, tmplen, ret;
620 SILC_LOG_DEBUG(("Parsing incoming packet"));
622 /* Check the length of the buffer */
623 if (buffer->len < SILC_PACKET_MIN_LEN) {
624 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
625 return SILC_PACKET_NONE;
628 /* Parse the buffer. This parses the SILC header of the packet. */
629 len = silc_buffer_unformat(buffer,
630 SILC_STR_UI_SHORT(&ctx->truelen),
631 SILC_STR_UI_CHAR(&ctx->flags),
632 SILC_STR_UI_CHAR(&ctx->type),
633 SILC_STR_UI_SHORT(&ctx->src_id_len),
634 SILC_STR_UI_SHORT(&ctx->dst_id_len),
635 SILC_STR_UI_CHAR(&ctx->src_id_type),
638 return SILC_PACKET_NONE;
640 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
641 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
642 SILC_LOG_ERROR(("Bad ID lengths in packet"));
643 return SILC_PACKET_NONE;
646 /* Calculate length of padding in packet. As this is special packet
647 the data area is not used in the padding calculation as it won't
648 be decrypted by the caller. */
649 tmplen = SILC_PACKET_HEADER_LEN + ctx->src_id_len + ctx->dst_id_len;
650 ctx->padlen = SILC_PACKET_PADLEN(tmplen);
652 silc_buffer_pull(buffer, len);
653 ret = silc_buffer_unformat(buffer,
654 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
656 SILC_STR_UI_CHAR(&ctx->dst_id_type),
657 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
659 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
662 return SILC_PACKET_NONE;
664 silc_buffer_push(buffer, len);
666 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
667 ctx->buffer->data, ctx->buffer->len);
669 /* Pull SILC header and padding from packet */
670 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
671 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
673 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
678 /* Allocate packet context */
680 SilcPacketContext *silc_packet_context_alloc(void)
682 SilcPacketContext *ctx = silc_calloc(1, sizeof(*ctx));
687 /* Increse the reference count of the packet context. */
689 SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx)
692 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users - 1,
697 /* Decrese the reference count of the packet context and free it only if
700 void silc_packet_context_free(SilcPacketContext *ctx)
703 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users + 1,
708 silc_buffer_free(ctx->buffer);
710 silc_free(ctx->src_id);
712 silc_free(ctx->dst_id);