From c826b9841053da3f00e2c531b25bb22aa49255d5 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Wed, 17 Oct 2001 18:31:16 +0000 Subject: [PATCH] updates. --- CHANGES | 25 ++++ apps/silcd/protocol.c | 16 +- apps/silcd/server.c | 4 - apps/silcd/server_backup.c | 52 ++++--- doc/draft-riikonen-silc-ke-auth-04.nroff | 5 + doc/draft-riikonen-silc-pp-04.nroff | 30 ++-- doc/draft-riikonen-silc-spec-04.nroff | 6 +- lib/silccore/silcchannel.c | 9 +- lib/silccore/silcpacket.c | 181 +++++++---------------- lib/silccore/silcpacket.h | 60 +++++--- lib/silccore/silcprivate.c | 9 +- lib/silccrypt/silccipher.h | 5 - lib/silccrypt/silchmac.c | 14 -- lib/silccrypt/silchmac.h | 5 +- lib/silccrypt/silcrng.c | 14 +- lib/silccrypt/silcrng.h | 10 +- lib/silcske/silcske.c | 8 - lib/silcutil/silcbuffmt.c | 68 ++++++++- lib/silcutil/silcbuffmt.h | 9 ++ prepare | 2 +- 20 files changed, 284 insertions(+), 248 deletions(-) diff --git a/CHANGES b/CHANGES index 427f1110..660045cb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,28 @@ +Wed Oct 17 16:51:18 EDT 2001 Pekka Riikonen + + * Added SILC_STR_UI8_[N]STRING[_ALLOC] formats to the + lib/silcutil/silcbuffmt.[ch]. + + * Redefined the SILC packet header to include the padding + length. Affected file lib/silccore/silcpacket.[ch]. + + * Added SILC_PACKET_PADLEN_MAX macro to return the padding + length for maximum padding up to 128 bytes). Affected + file lib/silccore/silcpacket.h. + + * Removed all backwards support for old 0.5.x MAC thingies. + The SILC packet header change makes it impossible to be + backwards compatible. + + * Send the ENDING packet with timeout in the backup resuming + protocol. This is to assure that all routers has connected + to the primary router. Affected file silcd/server_backup.c. + + * Changed the RNG to take the first IV from random data. It + used to take it from zero actually. Changed the RNG also + to use /dev/urandom during session. /dev/random is used + in initialization. Affected file lib/silccrypt/silcrng.[ch]. + Tue Oct 16 20:45:49 EDT 2001 Pekka Riikonen * Changed the SILC packet header to have the first two bytes diff --git a/apps/silcd/protocol.c b/apps/silcd/protocol.c index 50fdc707..c78ff8e2 100644 --- a/apps/silcd/protocol.c +++ b/apps/silcd/protocol.c @@ -244,15 +244,6 @@ int silc_server_protocol_ke_set_keys(SilcSKE ske, return FALSE; } - /* XXX backwards support for old MAC thingy - XXX Remove ing 0.7.x */ - if (ske->backward_version) { - silc_hmac_set_b(idata->hmac_send); - silc_hmac_set_b(idata->hmac_receive); - idata->send_key->back = TRUE; - idata->receive_key->back = TRUE; - } - if (is_responder == TRUE) { silc_cipher_set_key(idata->send_key, keymat->receive_enc_key, keymat->enc_key_len); @@ -369,10 +360,9 @@ SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version, if (min > min2) status = SILC_SKE_STATUS_BAD_VERSION; - /* Backwards support for 0.5.x for various MAC related issues. - XXX Remove in 0.7.x */ - if (maj == 0 && min < 6) - ske->backward_version = 1; + /* XXX < 0.6 is not allowed */ + if (maj == 0 && min < 5) + status = SILC_SKE_STATUS_BAD_VERSION; return status; } diff --git a/apps/silcd/server.c b/apps/silcd/server.c index bad68ba9..5192004d 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -1572,10 +1572,6 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real) SILC_LOG_DEBUG(("Start")); - /* XXX backwards support for 0.5.x - XXX remove in 0.7.x */ - packet->sock = sock; - /* Parse the packet */ if (parse_ctx->normal) ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL); diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index 2088dd9a..f997ef2f 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -650,6 +650,34 @@ static void silc_server_backup_connect_primary(SilcServer server, backup_router->protocol = NULL; } +SILC_TASK_CALLBACK(silc_server_backup_send_resumed) +{ + SilcProtocol protocol = (SilcProtocol)context; + SilcServerBackupProtocolContext ctx = protocol->context; + SilcServer server = ctx->server; + SilcBuffer packet; + int i; + + for (i = 0; i < ctx->sessions_count; i++) + if (ctx->sessions[i].server_entry == ctx->sock->user_data) + ctx->session = ctx->sessions[i].session; + + /* We've received all the CONNECTED packets and now we'll send the + ENDING packet to the new primary router. */ + packet = silc_buffer_alloc(2); + silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet)); + silc_buffer_format(packet, + SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_ENDING), + SILC_STR_UI_CHAR(ctx->session), + SILC_STR_END); + silc_server_packet_send(server, ctx->sock, + SILC_PACKET_RESUME_ROUTER, 0, + packet->data, packet->len, FALSE); + silc_buffer_free(packet); + + protocol->state = SILC_PROTOCOL_STATE_END; +} + /* Resume protocol with RESUME_ROUTER packet: SILC_PACKET_RESUME_ROUTER: @@ -922,24 +950,12 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) SILC_LOG_DEBUG(("********************************")); SILC_LOG_DEBUG(("Sending ENDING packet to primary")); - for (i = 0; i < ctx->sessions_count; i++) - if (ctx->sessions[i].server_entry == ctx->sock->user_data) - ctx->session = ctx->sessions[i].session; - - /* We've received all the CONNECTED packets and now we'll send the - ENDING packet to the new primary router. */ - packet = silc_buffer_alloc(2); - silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet)); - silc_buffer_format(packet, - SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_ENDING), - SILC_STR_UI_CHAR(ctx->session), - SILC_STR_END); - silc_server_packet_send(server, ctx->sock, - SILC_PACKET_RESUME_ROUTER, 0, - packet->data, packet->len, FALSE); - silc_buffer_free(packet); - - protocol->state = SILC_PROTOCOL_STATE_END; + /* Send with a timeout */ + silc_schedule_task_add(server->schedule, 0, + silc_server_backup_send_resumed, + protocol, 1, 0, SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); + return; } else { /* Responder */ diff --git a/doc/draft-riikonen-silc-ke-auth-04.nroff b/doc/draft-riikonen-silc-ke-auth-04.nroff index 6e493f9f..a8d57439 100644 --- a/doc/draft-riikonen-silc-ke-auth-04.nroff +++ b/doc/draft-riikonen-silc-ke-auth-04.nroff @@ -957,6 +957,11 @@ sent to the sender and the protocol execution fails. This is REQUIRED authentication method to be supported by all SILC implementations. +When password authentication is used it is RECOMMENDED that maximum +amount of padding is applied to the SILC packet. This way it is not +possible to approximate the length of the password from the encrypted +packet. + .ti 0 3.2.2 Public Key Authentication diff --git a/doc/draft-riikonen-silc-pp-04.nroff b/doc/draft-riikonen-silc-pp-04.nroff index bb44b7c5..29cec084 100644 --- a/doc/draft-riikonen-silc-pp-04.nroff +++ b/doc/draft-riikonen-silc-pp-04.nroff @@ -216,9 +216,10 @@ with malformed SILC header MUST be dropped. Padding follows the packet header. The purpose of the padding is to make the packet multiple by eight (8) or by the block size of the cipher used in the encryption, which ever is larger. The maximum -length of padding is currently 16 bytes. The padding is always -encrypted. See the section 2.7 Padding Generation for more detailed -information. +length of padding is currently 128 bytes. The padding is always +encrypted. The padding is applied always, even if the packet is +not encrypted. See the section 2.7 Padding Generation for more +detailed information. Data payload area follows padding and it is the actual data of the packet. The packet data is the packet payloads defined in this @@ -253,7 +254,7 @@ The following diagram represents the SILC packet header. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Payload Length | Flags | Packet Type | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Source ID Length | Destination ID Length | +| Pad Length | RESERVED | Source ID Len | Dest ID Len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Src ID Type | | +-+-+-+-+-+-+-+-+ + @@ -332,11 +333,18 @@ o Packet Type (1 byte) - Is the type of the packet. Receiver uses this field to parse the packet. See section 2.3 SILC Packets for list of defined packet types. -o Source ID Length (2 bytes) - Indicates the length of the +o Pad Length (1 byte) - Indicates the length of the padding + applied after the SILC Packet header. Maximum length for + padding is 128 bytes. + +o RESERVED (1 byte) - Reserved field and must include a + zero (0) value. + +o Source ID Length (1 byte) - Indicates the length of the Source ID field in the header, not including this or any other fields. -o Destination ID Length (2 bytes) - Indicates the length of the +o Destination ID Length (1 byte) - Indicates the length of the Destination ID field in the header, not including this or any other fields. @@ -355,6 +363,7 @@ o Destination ID (variable length) - The actual destination ID that indicates which is the end receiver of the packet. + .ti 0 2.3 SILC Packet Types @@ -2521,16 +2530,19 @@ of the cipher, which ever is larger. The padding is always encrypted. For normal packets the padding is added after the SILC Packet Header and between the Data Payload area. The padding for normal packets -are calculated as follows: +may be calculated as follows: .in 6 padding length = 16 - (packet_length mod block_size) .in 3 The `block_size' is the block size of the cipher. The maximum padding -length is 16 bytes, and minimum is 1 byte. The above algorithm calculates +length is 128 bytes, and minimum is 1 byte. The above algorithm calculates the padding to the next block size, and always returns the padding -length between 1 - 16 bytes. +length between 1 - 16 bytes. However, implementations may add padding +up to 128 bytes. For example packets that include a passphrase or a +password for authentication purposes SHOULD pad the packet up to the +maximum padding length. For special packets the padding calculation is different as special packets may be encrypted differently. In these cases the encrypted diff --git a/doc/draft-riikonen-silc-spec-04.nroff b/doc/draft-riikonen-silc-spec-04.nroff index 8071a22e..5d13832e 100644 --- a/doc/draft-riikonen-silc-spec-04.nroff +++ b/doc/draft-riikonen-silc-spec-04.nroff @@ -1139,7 +1139,11 @@ o Authentication Data (variable length) - Authentication If the authentication method is password based, the Authentication Data field includes the plaintext password. It is safe to send plaintext password since the entire payload is encrypted. In this -case the Public Data Length is set to zero (0). +case the Public Data Length is set to zero (0), but MAY also include +random data for padding purposes. It is also RECOMMENDED that maximum +amount of padding is applied to SILC packet when using password based +authentication. This way it is not possible to approximate the length +of the password from the encrypted packet. If the authentication method is public key based (or certificate) the Authentication Data is computed as follows: diff --git a/lib/silccore/silcchannel.c b/lib/silccore/silcchannel.c index 1edd0bcf..9ba67a7c 100644 --- a/lib/silccore/silcchannel.c +++ b/lib/silccore/silcchannel.c @@ -218,6 +218,8 @@ uint32 silc_channel_get_mode(SilcChannelPayload payload) ******************************************************************************/ +#define SILC_CHANNEL_MESSAGE_PAD(__payloadlen) (16 - (__payloadlen) % 16) + /* Channel Message Payload structure. Contents of this structure is parsed from SILC packets. */ struct SilcChannelMessagePayloadStruct { @@ -334,8 +336,8 @@ SilcBuffer silc_channel_message_payload_encode(uint16 flags, { int i; SilcBuffer buffer; - uint32 len, pad_len, mac_len, block_len; - unsigned char pad[SILC_PACKET_MAX_PADLEN]; + uint32 len, pad_len, mac_len; + unsigned char pad[16]; unsigned char mac[32]; SILC_LOG_DEBUG(("Encoding channel message payload")); @@ -343,9 +345,8 @@ SilcBuffer silc_channel_message_payload_encode(uint16 flags, /* Calculate length of padding. IV is not included into the calculation since it is not encrypted. */ mac_len = silc_hmac_len(hmac); - block_len = silc_cipher_get_block_len(cipher); len = 6 + data_len + mac_len; - pad_len = SILC_PACKET_PADLEN(len, block_len); + pad_len = SILC_CHANNEL_MESSAGE_PAD(len); /* Allocate channel payload buffer */ len += pad_len + iv_len; diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index f21ae66a..ddf54e00 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -89,14 +89,8 @@ void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, uint32 sequence, unsigned char psn[4]; silc_hmac_init(hmac); - - /* XXX Backwards support for old MAC computation. - XXX Remove in 0.7.x */ - if (!silc_hmac_get_b(hmac)) { - SILC_PUT32_MSB(sequence, psn); - silc_hmac_update(hmac, psn, 4); - } - + SILC_PUT32_MSB(sequence, psn); + silc_hmac_update(hmac, psn, 4); silc_hmac_update(hmac, buffer->data, buffer->len); silc_hmac_final(hmac, mac, &mac_len); silc_buffer_put_tail(buffer, mac, mac_len); @@ -107,13 +101,7 @@ void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, uint32 sequence, if (cipher) { SILC_LOG_DEBUG(("Encrypting packet, cipher %s, len %d", cipher->cipher->name, len)); - /* XXX Backwards support for 0.5.x - XXX Remove in 0.7.x */ - if (hmac && silc_hmac_get_b(hmac)) - silc_cipher_encrypt(cipher, buffer->data + 2, buffer->data + 2, - len - 1, cipher->iv); - else - silc_cipher_encrypt(cipher, buffer->data, buffer->data, len, cipher->iv); + silc_cipher_encrypt(cipher, buffer->data, buffer->data, len, cipher->iv); } /* Pull the HMAC into the visible data area in the buffer */ @@ -150,8 +138,10 @@ void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, uint32 sequence, 2 bytes Payload length 1 byte Flags 1 byte Packet type - 2 bytes Source ID Length - 2 bytes Destination ID Length + 1 byte Padding length + 1 byte RESERVED + 1 bytes Source ID Length + 1 bytes Destination ID Length 1 byte Source ID Type n bytes Source ID 1 byte Destination ID Type @@ -185,11 +175,10 @@ void silc_packet_assemble(SilcPacketContext *ctx, SilcCipher cipher) /* Calculate the length of the padding. The padding is calculated from the data that will be encrypted. */ if (!ctx->padlen) { - ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen, block_len); - /* XXX backwards support for 0.5.x - XXX remove in 0.7.x */ - if (cipher->back) - ctx->padlen = SILC_PACKET_PADLEN2(ctx->truelen, block_len); + if (ctx->long_pad) + ctx->padlen = SILC_PACKET_PADLEN_MAX(ctx->truelen); + else + ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen, block_len); } /* Put the start of the data section to the right place. */ @@ -210,8 +199,10 @@ void silc_packet_assemble(SilcPacketContext *ctx, SilcCipher cipher) SILC_STR_UI_SHORT(ctx->truelen), SILC_STR_UI_CHAR(ctx->flags), SILC_STR_UI_CHAR(ctx->type), - SILC_STR_UI_SHORT(ctx->src_id_len), - SILC_STR_UI_SHORT(ctx->dst_id_len), + SILC_STR_UI_CHAR(ctx->padlen), + SILC_STR_UI_CHAR(0), + SILC_STR_UI_CHAR(ctx->src_id_len), + SILC_STR_UI_CHAR(ctx->dst_id_len), SILC_STR_UI_CHAR(ctx->src_id_type), SILC_STR_UI_XNSTRING(ctx->src_id, ctx->src_id_len), SILC_STR_UI_CHAR(ctx->dst_id_type), @@ -352,28 +343,12 @@ void silc_packet_receive_process(SilcSocketConnection sock, while (sock->inbuf->len > 0) { /* Decrypt first 16 bytes of the packet */ - if (!SILC_IS_INBUF_PENDING(sock) && cipher) { - /* XXX backwards support for 0.5.x - XXX remove in 0.7.x */ - if (cipher->back) - silc_cipher_decrypt(cipher, sock->inbuf->data + 2, - sock->inbuf->data + 2, - SILC_PACKET_MIN_HEADER_LEN, cipher->iv); - else - silc_cipher_decrypt(cipher, sock->inbuf->data, sock->inbuf->data, - SILC_PACKET_MIN_HEADER_LEN, cipher->iv); - } + if (!SILC_IS_INBUF_PENDING(sock) && cipher) + silc_cipher_decrypt(cipher, sock->inbuf->data, sock->inbuf->data, + SILC_PACKET_MIN_HEADER_LEN, cipher->iv); /* Get packet lenght and full packet length with padding */ - SILC_PACKET_LENGTH(sock->inbuf, packetlen); - /* XXX backwards support for 0.5.x - XXX remove in 0.7.x */ - if (cipher && cipher->back) { - paddedlen = packetlen + SILC_PACKET_PADLEN2(packetlen, block_len); - paddedlen += 2; - } else { - paddedlen = packetlen + SILC_PACKET_PADLEN(packetlen, block_len); - } + SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen); /* Sanity checks */ if (packetlen < SILC_PACKET_MIN_LEN) { @@ -393,6 +368,7 @@ void silc_packet_receive_process(SilcSocketConnection sock, parse_ctx = silc_calloc(1, sizeof(*parse_ctx)); parse_ctx->packet = silc_packet_context_alloc(); parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len); + parse_ctx->packet->padlen = sock->inbuf->data[4]; parse_ctx->packet->sequence = sequence++; parse_ctx->sock = sock; parse_ctx->context = parser_context; @@ -458,14 +434,8 @@ static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer, memset(mac, 0, sizeof(mac)); silc_hmac_init(hmac); - - /* XXX Backwards support for old MAC computation. - XXX Remove in 0.7.x */ - if (!silc_hmac_get_b(hmac)) { - SILC_PUT32_MSB(sequence, psn); - silc_hmac_update(hmac, psn, 4); - } - + SILC_PUT32_MSB(sequence, psn); + silc_hmac_update(hmac, psn, 4); silc_hmac_update(hmac, buffer->data, buffer->len); silc_hmac_final(hmac, mac, &mac_len); @@ -507,15 +477,8 @@ static int silc_packet_decrypt_rest(SilcCipher cipher, SilcHmac hmac, /* Decrypt rest of the packet */ silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN); - /* XXX backwards support for 0.5.x - XXX remove in 0.7.x */ - if (cipher->back) - silc_cipher_decrypt(cipher, buffer->data + 2, buffer->data + 2, - buffer->len - 2, - cipher->iv); - else - silc_cipher_decrypt(cipher, buffer->data, buffer->data, buffer->len, - cipher->iv); + silc_cipher_decrypt(cipher, buffer->data, buffer->data, buffer->len, + cipher->iv); silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN); SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len), @@ -537,7 +500,7 @@ static int silc_packet_decrypt_rest_special(SilcCipher cipher, { /* Decrypt rest of the header plus padding */ if (cipher) { - uint16 truelen, len1, len2, padlen, blocklen; + uint16 len; /* Pull MAC from packet before decryption */ if (hmac) { @@ -551,45 +514,22 @@ static int silc_packet_decrypt_rest_special(SilcCipher cipher, SILC_LOG_DEBUG(("Decrypting rest of the header")); - SILC_GET16_MSB(len1, &buffer->data[4]); - SILC_GET16_MSB(len2, &buffer->data[6]); + /* padding length + src id len + dst id len + header length - 16 + bytes already decrypted, gives the rest of the encrypted packet */ + len = (((uint8)buffer->data[4] + (uint8)buffer->data[6] + + (uint8)buffer->data[7] + SILC_PACKET_HEADER_LEN) - + SILC_PACKET_MIN_HEADER_LEN); - blocklen = silc_cipher_get_block_len(cipher); - truelen = SILC_PACKET_HEADER_LEN + len1 + len2; - - /* XXX backwards support for 0.5.x - XXX remove in 0.7.x */ - if (cipher->back) { - padlen = SILC_PACKET_PADLEN2(truelen, blocklen); - len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN); - - silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN); - - if (len1 - 2 > buffer->len) { - SILC_LOG_DEBUG(("Garbage in header of packet, bad packet length, " - "packet dropped")); - return FALSE; - } - - silc_cipher_decrypt(cipher, buffer->data + 2, buffer->data + 2, - len1 - 2, cipher->iv); - } else { - blocklen = silc_cipher_get_block_len(cipher); - truelen = SILC_PACKET_HEADER_LEN + len1 + len2; - padlen = SILC_PACKET_PADLEN(truelen, blocklen); - len1 = (truelen + padlen) - SILC_PACKET_MIN_HEADER_LEN; - - silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN); - - if (len1 > buffer->len) { - SILC_LOG_DEBUG(("Garbage in header of packet, bad packet length, " - "packet dropped")); - return FALSE; - } - - silc_cipher_decrypt(cipher, buffer->data, buffer->data, len1, cipher->iv); + silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN); + if (len > buffer->len) { + SILC_LOG_DEBUG(("Garbage in header of packet, bad packet length, " + "packet dropped")); + return FALSE; } + silc_cipher_decrypt(cipher, buffer->data, buffer->data, len, cipher->iv); silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN); + SILC_LOG_HEXDUMP(("packet, len %d", buffer->len), + buffer->data, buffer->len); } return TRUE; @@ -648,8 +588,8 @@ static int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac, SilcPacketType silc_packet_parse(SilcPacketContext *ctx, SilcCipher cipher) { SilcBuffer buffer = ctx->buffer; + uint8 tmp; int len, ret; - int block_len = cipher ? silc_cipher_get_block_len(cipher) : 0; SILC_LOG_DEBUG(("Parsing incoming packet")); @@ -664,11 +604,13 @@ SilcPacketType silc_packet_parse(SilcPacketContext *ctx, SilcCipher cipher) SILC_STR_UI_SHORT(&ctx->truelen), SILC_STR_UI_CHAR(&ctx->flags), SILC_STR_UI_CHAR(&ctx->type), - SILC_STR_UI_SHORT(&ctx->src_id_len), - SILC_STR_UI_SHORT(&ctx->dst_id_len), + SILC_STR_UI_CHAR(&ctx->padlen), + SILC_STR_UI_CHAR(&tmp), + SILC_STR_UI_CHAR(&ctx->src_id_len), + SILC_STR_UI_CHAR(&ctx->dst_id_len), SILC_STR_UI_CHAR(&ctx->src_id_type), SILC_STR_END); - if (len == -1) + if (len == -1 || tmp != 0) return SILC_PACKET_NONE; if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN || @@ -678,9 +620,6 @@ SilcPacketType silc_packet_parse(SilcPacketContext *ctx, SilcCipher cipher) return SILC_PACKET_NONE; } - /* Calculate length of padding in packet */ - ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen, block_len); - silc_buffer_pull(buffer, len); ret = silc_buffer_unformat(buffer, SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id, @@ -693,15 +632,6 @@ SilcPacketType silc_packet_parse(SilcPacketContext *ctx, SilcCipher cipher) if (ret == -1) return SILC_PACKET_NONE; - /* XXX backwards support for 0.5.x - XXX remove in 0.7.x */ - silc_buffer_pull(buffer, - ctx->src_id_len + 1 + ctx->dst_id_len + ctx->padlen); - SILC_LOG_DEBUG(("**************** %d", buffer->len)); - if (buffer->len == 2) - ctx->padlen += 2; - silc_buffer_push(buffer, ret); - silc_buffer_push(buffer, len); SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len), @@ -726,8 +656,8 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx, SilcCipher cipher) { SilcBuffer buffer = ctx->buffer; - int len, tmplen, ret; - int block_len = cipher ? silc_cipher_get_block_len(cipher) : 0; + uint8 tmp; + int len, ret; SILC_LOG_DEBUG(("Parsing incoming packet")); @@ -742,11 +672,13 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx, SILC_STR_UI_SHORT(&ctx->truelen), SILC_STR_UI_CHAR(&ctx->flags), SILC_STR_UI_CHAR(&ctx->type), - SILC_STR_UI_SHORT(&ctx->src_id_len), - SILC_STR_UI_SHORT(&ctx->dst_id_len), + SILC_STR_UI_CHAR(&ctx->padlen), + SILC_STR_UI_CHAR(&tmp), + SILC_STR_UI_CHAR(&ctx->src_id_len), + SILC_STR_UI_CHAR(&ctx->dst_id_len), SILC_STR_UI_CHAR(&ctx->src_id_type), SILC_STR_END); - if (len == -1) { + if (len == -1 || tmp != 0) { SILC_LOG_ERROR(("Malformed packet header, packet dropped")); return SILC_PACKET_NONE; } @@ -758,17 +690,6 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx, return SILC_PACKET_NONE; } - /* Calculate length of padding in packet. As this is special packet - the data area is not used in the padding calculation as it won't - be decrypted by the caller. */ - tmplen = SILC_PACKET_HEADER_LEN + ctx->src_id_len + ctx->dst_id_len; - /* XXX backwards support for 0.5.x - XXX remove in 0.7.x */ - if (ctx->back) - ctx->padlen = SILC_PACKET_PADLEN2(tmplen, block_len); - else - ctx->padlen = SILC_PACKET_PADLEN(tmplen, block_len); - silc_buffer_pull(buffer, len); ret = silc_buffer_unformat(buffer, SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id, diff --git a/lib/silccore/silcpacket.h b/lib/silccore/silcpacket.h index 1e70334d..535d3f0f 100644 --- a/lib/silccore/silcpacket.h +++ b/lib/silccore/silcpacket.h @@ -43,7 +43,10 @@ #define SILC_PACKET_MIN_HEADER_LEN 16 /* Maximum padding length */ -#define SILC_PACKET_MAX_PADLEN 16 +#define SILC_PACKET_MAX_PADLEN 128 + +/* Default padding length */ +#define SILC_PACKET_DEFAULT_PADLEN 16 /* Minimum packet length */ #define SILC_PACKET_MIN_LEN (SILC_PACKET_HEADER_LEN + 1) @@ -206,31 +209,29 @@ typedef unsigned char SilcPacketFlags; ***/ typedef struct { SilcBuffer buffer; - SilcPacketType type; + + uint16 truelen; SilcPacketFlags flags; + SilcPacketType type; + uint8 padlen; unsigned char *src_id; - uint16 src_id_len; - unsigned char src_id_type; + uint8 src_id_len; + uint8 src_id_type; unsigned char *dst_id; - uint16 dst_id_len; - unsigned char dst_id_type; - - uint16 truelen; - uint16 padlen; + uint8 dst_id_len; + uint8 dst_id_type; /* Back pointers */ void *context; SilcSocketConnection sock; int users; + bool long_pad; /* Set to TRUE to use maximum padding + in packet (up to 256 bytes). */ uint32 sequence; - - /* XXX backwards support for 0.5.c - XXX remove in 0.7.x */ - bool back; } SilcPacketContext; /****s* silccore/SilcPacketAPI/SilcPacketParserContext @@ -315,9 +316,10 @@ typedef void (*SilcPacketParserCallback)(SilcPacketParserContext * * SOURCE */ -#define SILC_PACKET_LENGTH(__packet, __ret_truelen) \ -do { \ - SILC_GET16_MSB((__ret_truelen), (__packet)->data); \ +#define SILC_PACKET_LENGTH(__packet, __ret_truelen, __ret_paddedlen) \ +do { \ + SILC_GET16_MSB((__ret_truelen), (__packet)->data); \ + (__ret_paddedlen) = (__ret_truelen) + (__packet)->data[4]; \ } while(0) /***/ @@ -335,15 +337,27 @@ do { \ * SOURCE */ #define SILC_PACKET_PADLEN(__packetlen, __blocklen) \ - SILC_PACKET_MAX_PADLEN - (__packetlen) % \ - ((__blocklen) ? (__blocklen) : SILC_PACKET_MAX_PADLEN) + SILC_PACKET_DEFAULT_PADLEN - (__packetlen) % \ + ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN) /***/ -/* XXX Backwards support for 0.5.x - XXX Remove in 0.7.x */ -#define SILC_PACKET_PADLEN2(__packetlen, __blocklen) \ - SILC_PACKET_MAX_PADLEN - ((__packetlen) - 2 ) % \ - ((__blocklen) ? (__blocklen) : SILC_PACKET_MAX_PADLEN) +/****d* silccore/SilcPacketAPI/SILC_PACKET_PADLEN_MAX + * + * NAME + * + * #define SILC_PACKET_PADLEN_MAX ... + * + * DESCRIPTION + * + * Returns the length of the padding up to the maximum length, which + * is 128 butes. This is used by various library routines to determine + * needed padding length. + * + * SOURCE + */ +#define SILC_PACKET_PADLEN_MAX(__packetlen) \ + SILC_PACKET_MAX_PADLEN - (__packetlen) % SILC_PACKET_MAX_PADLEN +/***/ /* Prototypes */ diff --git a/lib/silccore/silcprivate.c b/lib/silccore/silcprivate.c index 64c6f4d9..db835878 100644 --- a/lib/silccore/silcprivate.c +++ b/lib/silccore/silcprivate.c @@ -29,6 +29,8 @@ ******************************************************************************/ +#define SILC_PRIVATE_MESSAGE_PAD(__payloadlen) (16 - (__payloadlen) % 16) + /* Private Message Payload structure. Contents of this structure is parsed from SILC packets. */ struct SilcPrivateMessagePayloadStruct { @@ -90,8 +92,8 @@ SilcBuffer silc_private_message_payload_encode(uint16 flags, { int i; SilcBuffer buffer; - uint32 len, pad_len = 0, block_len; - unsigned char pad[SILC_PACKET_MAX_PADLEN]; + uint32 len, pad_len = 0; + unsigned char pad[16]; SILC_LOG_DEBUG(("Encoding private message payload")); @@ -99,8 +101,7 @@ SilcBuffer silc_private_message_payload_encode(uint16 flags, if (cipher) { /* Calculate length of padding. */ - block_len = silc_cipher_get_block_len(cipher); - pad_len = SILC_PACKET_PADLEN(len, block_len); + pad_len = SILC_PRIVATE_MESSAGE_PAD(len); len += pad_len; /* Generate padding */ diff --git a/lib/silccrypt/silccipher.h b/lib/silccrypt/silccipher.h index fb3ec257..7f951ee8 100644 --- a/lib/silccrypt/silccipher.h +++ b/lib/silccrypt/silccipher.h @@ -63,11 +63,6 @@ typedef struct SilcCipherStruct { SilcCipherObject *cipher; void *context; unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; - - /* XXX Backwards support for 0.5.x - XXX Remove in 0.7.x */ - bool back; - void (*set_iv)(struct SilcCipherStruct *, const unsigned char *); void (*get_iv)(struct SilcCipherStruct *, unsigned char *); uint32 (*get_key_len)(struct SilcCipherStruct *); diff --git a/lib/silccrypt/silchmac.c b/lib/silccrypt/silchmac.c index 6293cea6..77dce315 100644 --- a/lib/silccrypt/silchmac.c +++ b/lib/silccrypt/silchmac.c @@ -32,10 +32,6 @@ struct SilcHmacStruct { unsigned char inner_pad[64]; unsigned char outer_pad[64]; void *hash_context; - - /* XXX backwards thingy for 0.5.x MAC computation. - XXX Remove in 0.7.x */ - bool backwards_support; }; /* List of dynamically registered HMACs. */ @@ -398,13 +394,3 @@ void silc_hmac_final(SilcHmac hmac, unsigned char *return_hash, if (return_len) *return_len = hmac->hmac->len; } - -void silc_hmac_set_b(SilcHmac hmac) -{ - hmac->backwards_support = TRUE; -} - -bool silc_hmac_get_b(SilcHmac hmac) -{ - return hmac->backwards_support; -} diff --git a/lib/silccrypt/silchmac.h b/lib/silccrypt/silchmac.h index a94d2b16..62492169 100644 --- a/lib/silccrypt/silchmac.h +++ b/lib/silccrypt/silchmac.h @@ -395,7 +395,7 @@ void silc_hmac_init_with_key(SilcHmac hmac, const unsigned char *key, void silc_hmac_update(SilcHmac hmac, const unsigned char *data, uint32 data_len); -/****f* silccrypt/SilcHMACAPI/silc_hmac_init +/****f* silccrypt/SilcHMACAPI/silc_hmac_final * * SYNOPSIS * @@ -415,7 +415,4 @@ void silc_hmac_update(SilcHmac hmac, const unsigned char *data, void silc_hmac_final(SilcHmac hmac, unsigned char *return_hash, uint32 *return_len); -void silc_hmac_set_b(SilcHmac hmac); -bool silc_hmac_get_b(SilcHmac hmac); - #endif diff --git a/lib/silccrypt/silcrng.c b/lib/silccrypt/silcrng.c index e9fe1c81..485a60aa 100644 --- a/lib/silccrypt/silcrng.c +++ b/lib/silccrypt/silcrng.c @@ -115,6 +115,7 @@ typedef struct SilcRngObjectStruct { SilcRngState state; SilcHash sha1; uint8 threshhold; + char *devrandom; } SilcRngObject; /* Allocates new RNG object. */ @@ -132,6 +133,8 @@ SilcRng silc_rng_alloc() new->state = NULL; silc_hash_alloc("sha1", &new->sha1); + new->devrandom = strdup("/dev/random"); + return new; } @@ -142,7 +145,8 @@ void silc_rng_free(SilcRng rng) if (rng) { memset(rng->pool, 0, sizeof(rng->pool)); memset(rng->key, 0, sizeof(rng->key)); - silc_free(rng->sha1); + silc_hash_free(rng->sha1); + silc_free(new->devrandom); silc_free(rng); } } @@ -185,6 +189,8 @@ void silc_rng_init(SilcRng rng) silc_rng_get_medium_noise(rng); silc_rng_get_hard_noise(rng); silc_rng_get_soft_noise(rng); + silc_free(rng->devrandom); + rng->devrandom = strdup("/dev/urandom"); } /* This function gets 'soft' noise from environment. */ @@ -275,8 +281,8 @@ static void silc_rng_get_hard_noise(SilcRng rng) char buf[32]; int fd, len, i; - /* Get noise from /dev/random if available */ - fd = open("/dev/random", O_RDONLY); + /* Get noise from /dev/[u]random if available */ + fd = open(rnd->devrandom, O_RDONLY); if (fd < 0) return; @@ -370,7 +376,7 @@ static void silc_rng_stir_pool(SilcRng rng) uint32 iv[5]; /* Get the IV */ - memcpy(iv, &rng->pool[SILC_RNG_POOLSIZE - 256], sizeof(iv)); + memcpy(iv, &rng->pool[16], sizeof(iv)); /* First CFB pass */ for (i = 0; i < SILC_RNG_POOLSIZE; i += 5) { diff --git a/lib/silccrypt/silcrng.h b/lib/silccrypt/silcrng.h index f0666aaf..d8eacad2 100644 --- a/lib/silccrypt/silcrng.h +++ b/lib/silccrypt/silcrng.h @@ -57,10 +57,10 @@ * Every time data is acquired from any source, the pool is stirred. The * stirring process performs an CFB (cipher feedback) encryption with SHA1 * algorithm to the entire random pool. First it acquires an IV (Initial - * Vector) from the constant location of the pool and performs the first CFB - * pass. Then it acquires a new encryption key from variable location of the - * pool and performs the second CFB pass. The encryption key thus is always - * acquired from unguessable data. + * Vector) from the constant (random) location of the pool and performs + * the first CFB pass. Then it acquires a new encryption key from variable + * location of the pool and performs the second CFB pass. The encryption + * key thus is always acquired from unguessable data. * * The encryption process to the entire random pool assures that it is * impossible to learn the input data to the random pool without breaking the @@ -89,7 +89,7 @@ * * The second threshhold gets hard noise from system and stirs the random * pool. The threshhold is reached after 160 bits of random output. After the - * noise is acquired (from /dev/random) the random pool is stirred and the + * noise is acquired (from /dev/urandom) the random pool is stirred and the * threshholds are set to zero. The process is repeated again after 64 bits of * output for first threshhold and after 160 bits of output for the second * threshhold. diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index 0a56e96c..1e25f554 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -1862,14 +1862,6 @@ SilcSKEStatus silc_ske_process_key_material(SilcSKE ske, req_hmac_key_len, ske->prop->hash, key); - /* Backwards support for old MAC keys */ - /* XXX Remove in 0.7.x */ - if (ske->backward_version == 1) { - silc_free(key->receive_hmac_key); - key->receive_hmac_key = silc_calloc(1, sizeof(*key->receive_hmac_key)); - memcpy(key->receive_hmac_key, key->send_hmac_key, key->hmac_key_len); - } - memset(tmpbuf, 0, klen); silc_free(tmpbuf); silc_buffer_free(buf); diff --git a/lib/silcutil/silcbuffmt.c b/lib/silcutil/silcbuffmt.c index cc1a4ce2..86edee11 100644 --- a/lib/silcutil/silcbuffmt.c +++ b/lib/silcutil/silcbuffmt.c @@ -136,8 +136,10 @@ int silc_buffer_format_vp(SilcBuffer dst, va_list ap) silc_buffer_pull(dst, 8); break; } + case SILC_BUFFER_PARAM_UI8_STRING: case SILC_BUFFER_PARAM_UI16_STRING: case SILC_BUFFER_PARAM_UI32_STRING: + case SILC_BUFFER_PARAM_UI8_STRING_ALLOC: case SILC_BUFFER_PARAM_UI16_STRING_ALLOC: case SILC_BUFFER_PARAM_UI32_STRING_ALLOC: { @@ -148,9 +150,11 @@ int silc_buffer_format_vp(SilcBuffer dst, va_list ap) silc_buffer_pull(dst, tmp_len); break; } + case SILC_BUFFER_PARAM_UI8_NSTRING: case SILC_BUFFER_PARAM_UI16_NSTRING: case SILC_BUFFER_PARAM_UI32_NSTRING: case SILC_BUFFER_PARAM_UI_XNSTRING: + case SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC: case SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC: case SILC_BUFFER_PARAM_UI32_NSTRING_ALLOC: case SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC: @@ -284,6 +288,19 @@ int silc_buffer_unformat_vp(SilcBuffer src, va_list ap) silc_buffer_pull(src, 8); break; } + case SILC_BUFFER_PARAM_UI8_STRING: + { + uint8 len2; + unsigned char **x = va_arg(ap, unsigned char **); + HAS_SPACE(src, 1); + len2 = (uint8)src->data[0]; + silc_buffer_pull(src, 1); + HAS_SPACE(src, len2); + if (x) + *x = src->data; + silc_buffer_pull(src, len2); + break; + } case SILC_BUFFER_PARAM_UI16_STRING: { uint16 len2; @@ -297,6 +314,21 @@ int silc_buffer_unformat_vp(SilcBuffer src, va_list ap) silc_buffer_pull(src, len2); break; } + case SILC_BUFFER_PARAM_UI8_STRING_ALLOC: + { + uint8 len2; + unsigned char **x = va_arg(ap, unsigned char **); + HAS_SPACE(src, 1); + len2 = (uint8)src->data[0]; + silc_buffer_pull(src, 1); + HAS_SPACE(src, len2); + if (x && len2) { + *x = silc_calloc(len2 + 1, sizeof(unsigned char)); + memcpy(*x, src->data, len2); + } + silc_buffer_pull(src, len2); + break; + } case SILC_BUFFER_PARAM_UI16_STRING_ALLOC: { uint16 len2; @@ -340,11 +372,27 @@ int silc_buffer_unformat_vp(SilcBuffer src, va_list ap) silc_buffer_pull(src, len2); break; } + case SILC_BUFFER_PARAM_UI8_NSTRING: + { + uint8 len2; + unsigned char **x = va_arg(ap, unsigned char **); + uint8 *len = va_arg(ap, uint8 *); + HAS_SPACE(src, 1); + len2 = (uint8)src->data[0]; + silc_buffer_pull(src, 1); + HAS_SPACE(src, len2); + if (len) + *len = len2; + if (x) + *x = src->data; + silc_buffer_pull(src, len2); + break; + } case SILC_BUFFER_PARAM_UI16_NSTRING: { uint16 len2; unsigned char **x = va_arg(ap, unsigned char **); - uint16 *len = va_arg(ap, unsigned short *); + uint16 *len = va_arg(ap, uint16 *); HAS_SPACE(src, 2); SILC_GET16_MSB(len2, src->data); silc_buffer_pull(src, 2); @@ -356,6 +404,24 @@ int silc_buffer_unformat_vp(SilcBuffer src, va_list ap) silc_buffer_pull(src, len2); break; } + case SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC: + { + uint8 len2; + unsigned char **x = va_arg(ap, unsigned char **); + uint8 *len = va_arg(ap, uint8 *); + HAS_SPACE(src, 1); + len2 = (uint8)src->data[0]; + silc_buffer_pull(src, 1); + HAS_SPACE(src, len2); + if (len) + *len = len2; + if (x && len2) { + *x = silc_calloc(len2 + 1, sizeof(unsigned char)); + memcpy(*x, src->data, len2); + } + silc_buffer_pull(src, len2); + break; + } case SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC: { uint16 len2; diff --git a/lib/silcutil/silcbuffmt.h b/lib/silcutil/silcbuffmt.h index c22b6f05..3630d53a 100644 --- a/lib/silcutil/silcbuffmt.h +++ b/lib/silcutil/silcbuffmt.h @@ -47,10 +47,14 @@ typedef enum { SILC_BUFFER_PARAM_SI64_INT, SILC_BUFFER_PARAM_UI64_INT, + SILC_BUFFER_PARAM_UI8_STRING, /* No copy */ + SILC_BUFFER_PARAM_UI8_STRING_ALLOC, /* Alloc + memcpy */ SILC_BUFFER_PARAM_UI16_STRING, /* No copy */ SILC_BUFFER_PARAM_UI16_STRING_ALLOC, /* Alloc + memcpy */ SILC_BUFFER_PARAM_UI32_STRING, /* No copy */ SILC_BUFFER_PARAM_UI32_STRING_ALLOC, /* Alloc + memcpy */ + SILC_BUFFER_PARAM_UI8_NSTRING, /* No copy */ + SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC, /* Alloc + memcpy */ SILC_BUFFER_PARAM_UI16_NSTRING, /* No copy */ SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC, /* Alloc + memcpy */ SILC_BUFFER_PARAM_UI32_NSTRING, /* No copy */ @@ -137,6 +141,8 @@ typedef enum { as argument in unformatting. */ +#define SILC_STR_UI8_STRING(x) SILC_BUFFER_PARAM_UI8_STRING, (x) +#define SILC_STR_UI8_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI8_STRING_ALLOC, (x) #define SILC_STR_UI16_STRING(x) SILC_BUFFER_PARAM_UI16_STRING, (x) #define SILC_STR_UI16_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI16_STRING_ALLOC, (x) #define SILC_STR_UI32_STRING(x) SILC_BUFFER_PARAM_UI32_STRING, (x) @@ -172,6 +178,9 @@ typedef enum { as argument in unformatting. */ +#define SILC_STR_UI8_NSTRING(x, l) SILC_BUFFER_PARAM_UI8_NSTRING, (x), (l) +#define SILC_STR_UI8_NSTRING_ALLOC(x, l) \ + SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC, (x), (l) #define SILC_STR_UI16_NSTRING(x, l) SILC_BUFFER_PARAM_UI16_NSTRING, (x), (l) #define SILC_STR_UI16_NSTRING_ALLOC(x, l) \ SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC, (x), (l) diff --git a/prepare b/prepare index 0f7b15b8..8942bf63 100755 --- a/prepare +++ b/prepare @@ -37,7 +37,7 @@ # SILC Distribution versions. Set here or give the version on the command # line as argument. # -SILC_VERSION=0.6 # Base version +SILC_VERSION=0.6.1 # Base version ############################################################################# -- 2.24.0