+Wed Oct 17 16:51:18 EDT 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * 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 <priikone@silcnet.org>
* Changed the SILC packet header to have the first two bytes
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);
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;
}
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);
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:
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 */
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
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload Length | Flags | Packet Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-| Source ID Length | Destination ID Length |
+| Pad Length | RESERVED | Source ID Len | Dest ID Len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Src ID Type | |
+-+-+-+-+-+-+-+-+ +
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.
ID that indicates which is the end receiver of the packet.
+
.ti 0
2.3 SILC Packet Types
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
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:
******************************************************************************/
+#define SILC_CHANNEL_MESSAGE_PAD(__payloadlen) (16 - (__payloadlen) % 16)
+
/* Channel Message Payload structure. Contents of this structure is parsed
from SILC packets. */
struct SilcChannelMessagePayloadStruct {
{
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"));
/* 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;
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);
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 */
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
/* 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. */
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),
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) {
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;
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);
/* 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),
{
/* 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) {
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;
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"));
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 ||
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,
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),
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"));
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;
}
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,
#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)
***/
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
*
* 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)
/***/
* 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 */
******************************************************************************/
+#define SILC_PRIVATE_MESSAGE_PAD(__payloadlen) (16 - (__payloadlen) % 16)
+
/* Private Message Payload structure. Contents of this structure is parsed
from SILC packets. */
struct SilcPrivateMessagePayloadStruct {
{
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"));
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 */
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 *);
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. */
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;
-}
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
*
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
SilcRngState state;
SilcHash sha1;
uint8 threshhold;
+ char *devrandom;
} SilcRngObject;
/* Allocates new RNG object. */
new->state = NULL;
silc_hash_alloc("sha1", &new->sha1);
+ new->devrandom = strdup("/dev/random");
+
return new;
}
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);
}
}
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. */
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;
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) {
* 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
*
* 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.
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);
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:
{
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:
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;
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;
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);
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;
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 */
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)
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)
# 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
#############################################################################