--- channels.c Mon Sep 17 22:53:12 2001 +++ channels.new.c Mon Oct 15 14:28:43 2001 @@ -25,6 +25,32 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. + *************************************************************************** + * + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/13/2001. + *************************************************************************** * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -1590,9 +1616,12 @@ /* If there is data to send to the connection, enqueue some of it now. */ - +/* + * SD Mod: add arguments bogus_send_count and use_steno_timing_manipulation + * to channel_output_poll. +*/ void -channel_output_poll() +channel_output_poll(int *bogus_send_count, int use_steno_timing_manipulation) { int len, i; Channel *c; @@ -1649,11 +1678,49 @@ SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA); packet_put_int(c->remote_id); packet_put_string(buffer_ptr(&c->input), len); + /* + * Begin SD Mod: if using SSH2 and it is + * desired to use timing manipulation, reset + * counter since len > 0 implies packet will + * contain geniune data. + */ + if(compat20 && use_steno_timing_manipulation) + { + (*bogus_send_count)=0; + debug2("reseting count"); + } + /* End SD Mod */ packet_send(); buffer_consume(&c->input, len); c->remote_window -= len; } - } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) { + } + /* + * Begin SD Mod: + * packet does not contain data, we are not in a draining + * state and timing manipulation is desired, check if bogus + * count is below threshold. + */ + else if ((len = buffer_len(&c->input)) == 0 + && !(c->istate == CHAN_INPUT_WAIT_DRAIN) + && use_steno_timing_manipulation) { + /* + * If we have not sent too many bogus packets, sent a 16 + * byte ignore packet filled with garbage data and update + * the bogus_send_count; + */ + + if((*bogus_send_count) < 20){ + debug2("sending garbage packet"); + packet_send_ignore(16); + packet_send(); + (*bogus_send_count)++; + } + else + debug("max number of timeouts exceeded: stop sending garbage packets"); + } + /* End SD Mod */ + else if (c->istate == CHAN_INPUT_WAIT_DRAIN) { if (compat13) fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3"); /* --- channels.h Mon Sep 17 22:51:14 2001 +++ channels.new.h Mon Oct 15 14:28:43 2001 @@ -21,6 +21,33 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * + *************************************************************************** + * + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/13/2001. + *************************************************************************** + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. @@ -173,7 +200,15 @@ void channel_prepare_select(fd_set **, fd_set **, int *, int*, int); void channel_after_select(fd_set *, fd_set *); -void channel_output_poll(void); + +/* + * SD Mod: added parameters bogus_send_count, and use_steno_timing_manipulation. + * The bogus_send_count keeps track of how many bogus packets have been sent since + * the last packet containing real data. The use_steno_timining_manipulation flag + * keeps track of whether to perform timing analysis evasion. + */ +void channel_output_poll(int *bogus_send_count, int use_steno_timing_manipulation); + int channel_not_very_much_buffered_data(void); void channel_close_all(void); --- clientloop.c Mon Sep 17 22:51:14 2001 +++ clientloop.new.c Mon Oct 15 14:28:43 2001 @@ -46,6 +46,33 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * + *************************************************************************** + * + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/13/2001. + *************************************************************************** + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. @@ -315,16 +342,25 @@ * Waits until the client can do something (some data becomes available on * one of the file descriptors). */ - -static void +/* + * SD Mod: We changed the return value of client_wait_until_can_do_something + * from void to int. It now returns 1 if the steno_timer has expired and 0 if not. + */ +int client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, int *nallocp, int rekeying) { + /* SD Mod: added variable steno_timer */ + static struct timeval steno_timer = {0, 50000}; + + int return_val = 0; + long int prev_timer_val = 0; + /* Add any selections by the channel mechanism. */ channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); if (!compat20) { - /* Read from the connection, unless our buffers are full. */ + /* Read from the connection, unless our buffers are full. */ if (buffer_len(&stdout_buffer) < buffer_high && buffer_len(&stderr_buffer) < buffer_high && channel_not_very_much_buffered_data()) @@ -342,13 +378,7 @@ if (buffer_len(&stderr_buffer) > 0) FD_SET(fileno(stderr), *writesetp); } else { - /* channel_prepare_select could have closed the last channel */ - if (session_closed && !channel_still_open()) { - if (!packet_have_data_to_write()) - return; - } else { - FD_SET(connection_in, *readsetp); - } + FD_SET(connection_in, *readsetp); } /* Select server connection if have data to write to the server. */ @@ -363,9 +393,34 @@ * it: just have a random timeout for the select, and send a random * SSH_MSG_IGNORE packet when the timeout expires. */ + + /* + * Begin SD Mod: + * Enforce wait send packets every 50 ms. To do this add timer to + * select loop. Buffer input as it comes and force the timer to decrement + * if select call does not do so. + */ + prev_timer_val = steno_timer.tv_usec; + + return_val = select((*maxfdp)+1, *readsetp, *writesetp, NULL, &steno_timer); - if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) { - char buf[100]; + /* SD Mod continued: + * If the prev_timer_val is still equal to the steno_timer.tv_usec value + * then select did not decrement timer. So force decrement so timer can + * expire. This problem arises since the file descriptors change since they + * were reset just prior to entering the select loop. This is a strange + * fix but it works. + */ + + if(prev_timer_val == steno_timer.tv_usec){ + debug3("decrementing timer forcefully"); + steno_timer.tv_usec -= 100; + } + + if(return_val < 0){ + /* end of SD Mod */ + + char buf[100]; /* * We have to clear the select masks, because we return. @@ -376,14 +431,29 @@ memset(*writesetp, 0, *maxfdp); if (errno == EINTR) - return; + return 0; /* Note: we might still have data in the buffers. */ snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); buffer_append(&stderr_buffer, buf, strlen(buf)); quit_pending = 1; } + /* + * Begin SD Mod: Return to the caller whether the timer has + * expired or not. It is possible that the forced decrement caused + * the timer value to bbecome negative, if so the consider the + * timer expired, reset it and return 1 to the caller denoting timer + * expiration. + */ + if(steno_timer.tv_usec <= 0) + { + steno_timer.tv_usec = 50000; + return 1; + } + else + return 0; + /* End SD Mod */ + } - static void client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) { @@ -773,6 +843,15 @@ int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0; char buf[100]; + /* + * Begin SD Mod: + * Add counter for number of fake packets that have been sent. + * Add time_out flag for marking when timeout has occured. + */ + int bogus_send_count = 0; + int time_out = 0; + /* End SD Mod */ + debug("Entering interactive session."); start_time = get_current_time(); @@ -861,9 +940,16 @@ * Make packets from buffered channel data, and * enqueue them for sending to the server. */ - if (packet_not_very_much_data_to_write()) - channel_output_poll(); - + /* + * Begin SD Mod: on expiration of 50 ms timer call + * channel_ouput + */ + if(time_out){ + channel_output_poll(&bogus_send_count,options.use_steno_timing_manipulation); + time_out = 0; + } + /* End SD Mod */ + /* * Check if the window size has changed, and buffer a * message about it to the server if so. @@ -878,8 +964,10 @@ * available on one of the descriptors). */ max_fd2 = max_fd; - client_wait_until_can_do_something(&readset, &writeset, - &max_fd2, &nalloc, rekeying); + + /* SD Mod: wait for data or timeout */ + time_out = client_wait_until_can_do_something(&readset, + &writeset, &max_fd2, &nalloc, rekeying); if (quit_pending) break; @@ -1222,6 +1310,21 @@ exit_status = packet_get_int(); packet_done(); } + /* + * Begin SD Mod: + * check to see if request from server is to turn off steno. + * If so, turn it off if neccessary. + */ + else if (strcmp(rtype, "no_steno") == 0) { + debug("received request not use use steno"); + if(options.use_steno_timing_manipulation) + { + options.use_steno_timing_manipulation = 0; + } + success = 1; + packet_done(); + } + /* End SD Mod */ if (reply) { packet_start(success ? SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); --- readconf.c Wed Sep 19 17:57:56 2001 +++ readconf.new.c Mon Oct 15 14:28:43 2001 @@ -9,6 +9,32 @@ * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". + * + *************************************************************************** + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/3/2001. + *************************************************************************** */ #include "includes.h" @@ -793,6 +819,12 @@ options->preferred_authentications = NULL; options->bind_address = NULL; options->smartcard_device = NULL; + /* + * SD Mod: Initialize option to use steno timing manipulation. + * By default, timing analysis evasion is used. The -S flag + * must be used to turn off this feature. + */ + options->use_steno_timing_manipulation = 1; } /* --- readconf.h Wed Sep 19 17:57:56 2001 +++ readconf.new.h Mon Oct 15 14:28:43 2001 @@ -9,6 +9,32 @@ * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". + * + *************************************************************************** + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/3/2001. + *************************************************************************** */ /* RCSID("$OpenBSD: readconf.h,v 1.39 2001/09/19 19:24:18 stevesk Exp $"); */ @@ -101,6 +127,14 @@ int num_remote_forwards; Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION]; int clear_forwardings; + + /* + * SD Mod: Added option to use steno timing manipulation. + * By default, timing analysis evasion is used. The -S flag + * must be used to turn off this feature. + */ + int use_steno_timing_manipulation; + } Options; --- servconf.c Wed Sep 12 09:32:15 2001 +++ servconf.new.c Mon Oct 15 14:28:43 2001 @@ -7,6 +7,32 @@ * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". + *************************************************************************** + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/3/2001. + *************************************************************************** + * */ #include "includes.h" @@ -105,6 +131,12 @@ options->authorized_keys_file = NULL; options->authorized_keys_file2 = NULL; options->pam_authentication_via_kbd_int = -1; + /* + * SD Mod: Initialize option to use steno timing manipulation. + * By default, timing analysis evasion is used. The -S flag + * must be used to turn off this feature. + */ + options->use_steno_timing_manipulation = 1; } void --- servconf.h Wed Sep 12 09:40:06 2001 +++ servconf.new.h Mon Oct 15 14:28:43 2001 @@ -9,6 +9,32 @@ * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". + *************************************************************************** + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/3/2001. + *************************************************************************** + * */ /* RCSID("$OpenBSD: servconf.h,v 1.49 2001/08/17 18:59:47 stevesk Exp $"); */ @@ -129,7 +155,12 @@ char *authorized_keys_file; /* File containing public keys */ char *authorized_keys_file2; int pam_authentication_via_kbd_int; - + /* + * SD Mod: Added option to use steno timing manipulation. + * By default, timing analysis evasion is used. The -S flag + * must be used to turn off this feature. + */ + int use_steno_timing_manipulation; } ServerOptions; void initialize_server_options(ServerOptions *); --- serverloop.c Mon Sep 17 22:53:13 2001 +++ serverloop.new.c Mon Oct 15 14:28:43 2001 @@ -21,6 +21,31 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. + *************************************************************************** + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/13/2001. + *************************************************************************** * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -167,15 +192,24 @@ * have data or can accept data. Optionally, a maximum time can be specified * for the duration of the wait (0 = infinite). */ -static void + +/* + * SD Mod: + * We changed wait_until_can_do_something's return value from void + * to int. It now returns 1 if the steno_timer has expired and 0 if not. + */ +int wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, int *nallocp, u_int max_time_milliseconds) { - struct timeval tv, *tvp; + + struct timeval tv, *tvp; + /* SD Mod: added variable steno_timer*/ + static struct timeval steno_timer = {0, 50000}; int ret; int client_alive_scheduled = 0; - - /* + long int prev_timer_val = 0; + /* * if using client_alive, set the max timeout accordingly, * and indicate that this particular timeout was for client * alive by setting the client_alive_scheduled flag. @@ -183,11 +217,11 @@ * this could be randomized somewhat to make traffic * analysis more difficult, but we're not doing it yet. */ - if (compat20 && - max_time_milliseconds == 0 && options.client_alive_interval) { - client_alive_scheduled = 1; + if (max_time_milliseconds == 0 && options.client_alive_interval) { + client_alive_scheduled = 1; max_time_milliseconds = options.client_alive_interval * 1000; - } + } else + client_alive_scheduled = 0; /* When select fails we restart from here. */ retry_select: @@ -199,7 +233,8 @@ /* wrong: bad condition XXX */ if (channel_not_very_much_buffered_data()) FD_SET(connection_in, *readsetp); - } else { + +} else { /* * Read packets from the client unless we have too much * buffered stdin or channel data. @@ -250,8 +285,21 @@ if (tvp!=NULL) debug3("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds); + + /* SD Mod: if select does not decrement timer, force it.*/ + prev_timer_val = steno_timer.tv_usec; + + ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, &steno_timer); + + if(prev_timer_val == steno_timer.tv_usec) + { + debug3 ("decrementing timer forcefully"); + steno_timer.tv_usec -= 100; + } + /* End SD Mod */ + /* Wait for something to happen, or the timeout to expire. */ - ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); + if (ret == -1) { if (errno != EINTR) @@ -259,9 +307,11 @@ else goto retry_select; } + if (ret == 0 && client_alive_scheduled) { /* timeout, check to see how many we have had */ - client_alive_timeouts++; + + client_alive_timeouts++; if (client_alive_timeouts > options.client_alive_count_max ) { packet_disconnect( @@ -282,9 +332,27 @@ packet_disconnect( "No open channels after timeout!"); } - } + } + + /* + * Begin SD Mod: Return to the caller whether the timer has + * expired or not. It is possible that the forced decrement caused + * the timer value to bbecome negative, if so the consider the + * timer expired, reset it and return 1 to the caller denoting timer + * expiration. + */ + if(steno_timer.tv_usec <= 0) + { + steno_timer.tv_usec = 50000; + return 1; + } + else + return 0; + /* End SD Mod */ + } + /* * Processes input from the client and the program. Input data is stored * in buffers and processed later. @@ -448,6 +516,13 @@ u_int stdout_buffer_bytes; int type; + /* + * Begin SD Mod: + * NOT USED only here for compatibility with channel_output_poll(). + */ + int bogus_send_count = 0; + /* End SD Mod */ + debug("Entering interactive session."); /* Initialize the SIGCHLD kludge. */ @@ -549,8 +624,15 @@ previous_stdout_buffer_bytes = buffer_len(&stdout_buffer); /* Send channel data to the client. */ - if (packet_not_very_much_data_to_write()) - channel_output_poll(); + /* + * Begin SD Mod: use bogus_send_count to comply + * with channel_output_poll definition. + */ + if(packet_not_very_much_data_to_write()) + channel_output_poll(&bogus_send_count,0); + /* + * End SD Mod + */ /* * Bail out of the loop if the program has closed its output @@ -579,7 +661,7 @@ max_fd = MAX(max_fd, fderr); /* Sleep in select() until we can do something. */ - wait_until_can_do_something(&readset, &writeset, &max_fd, + wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, max_time_milliseconds); /* Process any channel events. */ @@ -676,6 +758,14 @@ int rekeying = 0, max_fd, status, nalloc = 0; pid_t pid; + /* + * Begin SD Mod: + * NOT USED only here for compatibility with channel_output_poll(). + */ + int bogus_send_count = 0 ; + int time_out = 0; + /* End SD Mod */ + debug("Entering interactive session for SSH2."); mysignal(SIGCHLD, sigchld_handler); @@ -692,30 +782,44 @@ process_buffered_input_packets(); rekeying = (xxx_kex != NULL && !xxx_kex->done); - - if (!rekeying && packet_not_very_much_data_to_write()) - channel_output_poll(); - wait_until_can_do_something(&readset, &writeset, &max_fd, - &nalloc, 0); + + /* + * Begin SD Mod: send packets only when not rekeying and + * 50 ms timer has expired. + */ + if (!rekeying && time_out) + { + channel_output_poll(&bogus_send_count,options.use_steno_timing_manipulation); + time_out = 0; + } + + + /* + * SD Mod: added time_out flag to record when + * 50 ms timer has expired. + */ + time_out = wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, rekeying); + /* End SD Mod */ + if (child_terminated) { - while ((pid = waitpid(-1, &status, WNOHANG)) > 0) - session_close_by_pid(pid, status); - child_terminated = 0; + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + session_close_by_pid(pid, status); + child_terminated = 0; } if (!rekeying) - channel_after_select(readset, writeset); + channel_after_select(readset, writeset); process_input(readset); if (connection_closed) - break; + break; process_output(writeset); } if (readset) - xfree(readset); + xfree(readset); if (writeset) - xfree(writeset); + xfree(writeset); mysignal(SIGCHLD, SIG_DFL); - + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) session_close_by_pid(pid, status); /* @@ -894,6 +998,17 @@ packet_put_int(c->local_maxpacket); packet_send(); } + /* + * SD Mod: if -S option is used, request + * client to not use stenographic timing manipulation as well. + */ + if(!options.use_steno_timing_manipulation) + { + debug("sending no steno msg"); + channel_request(c->remote_id,"no_steno",0); + } + /* End SD Mod */ + } else { debug("server_input_channel_open: failure %s", ctype); packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); --- session.c Sun Sep 16 15:17:15 2001 +++ session.new.c Mon Oct 15 14:28:43 2001 @@ -20,6 +20,32 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * + *************************************************************************** + * + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/13/2001. + *************************************************************************** * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. @@ -1726,6 +1752,24 @@ return 1; } + +/* + * Begin SD Mod: This function is added to handle a request from the + * client to turn off steno timing manipulation. + */ +int +session_no_steno_req(Session *s) +{ + packet_done(); + debug("handling steno request"); + if(options.use_steno_timing_manipulation) + { + options.use_steno_timing_manipulation = 0; + } + return 1; +} +/* End SD Mod */ + static int session_exec_req(Session *s) { @@ -1795,6 +1839,14 @@ } else if (strcmp(rtype, "subsystem") == 0) { success = session_subsystem_req(s); } + /* + * Begin SD Mod: Handle request from the client + * to turn off server's timing manipulation. + */ + else if (strcmp(rtype, "no_steno") == 0) { + success = session_no_steno_req(s); + } + /* End SD Mod */ } if (strcmp(rtype, "window-change") == 0) { success = session_window_change_req(s); --- ssh.c Mon Sep 24 15:04:03 2001 +++ ssh.new.c Mon Oct 15 14:28:43 2001 @@ -26,6 +26,31 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * + * *************************************************************************** + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/3/2001. + *************************************************************************** * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. @@ -205,6 +230,8 @@ fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); fprintf(stderr, " -s Invoke command (mandatory) as SSH2 subsystem.\n"); fprintf(stderr, " -b addr Local IP address.\n"); + /* SD Mod: */ + fprintf(stderr, " -S Don't use stenographic timing manipulation\n"); exit(1); } @@ -319,8 +346,9 @@ host = NULL; again: + /* SD Mod: add s option to getopt() call */ while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) { + "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:STVX")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -525,6 +553,14 @@ case 's': subsystem_flag = 1; break; + /* + * Begin SD Mod: Add case to handle option to turn off + * steno timing manipulation. + */ + case 'S': + options.use_steno_timing_manipulation = 0; + break; + /* End SD Mod */ case 'b': options.bind_address = optarg; break; @@ -1080,6 +1116,20 @@ channel_request_start(id, "auth-agent-req@openssh.com", 0); packet_send(); } + + /* + * Begin SD Mod: If the client has the option to turn of timing + * manipulation set, send a request message to the server to + * turn off its timing manipulation. + */ + if (!options.use_steno_timing_manipulation) + { + debug("sending request for no steno."); + channel_request_start(id, "no_steno",0); + packet_send(); + } + /* End SD Mod */ + len = buffer_len(&command); if (len > 0) { --- sshd.c Mon Sep 17 21:03:04 2001 +++ sshd.new.c Mon Oct 15 14:28:43 2001 @@ -26,6 +26,31 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. + * *************************************************************************** + * Timing Analysis Evasion changes were developed by C. Jason Coit and Roel + * Jonkman of Silicon Defense. + * + * These changes cause SSH to send packets unless requested not to, exactly + * every 50 ms. If no data is ready to be sent, SSH will send a bogus packet + * with 16 bytes of data (which is the same size as most keystrokes). Thus + * someone performing timing analysis cannot determine the inter keystroke + * timing of a user. SSH will send bogus data for about 1 sec after the last + * keystroke. This both increases the difficulty of determing exact password + * lengths and conserves bandwith when a user is idle (e.g. taking a coffee break). + * Both the server and the client exhibit this behavior and yet our code places no + * limit on the data rate (i.e if the server needs to respond with large amounts + * of data it will be about to do so with large packets able to do so with large + * packets and without the 50 ms timing constraint). + * + * All changes were developed in response to timing analysis attack on ssh + * published by Dawn Song et. al. + * + * The evasion methods are only applicable to SSH2. All single line changes + * and small comments are marked by SD Mod. All multiline modifications are + * delimited by Begin SD Mod and End SD Mod. + * + * The last change was committed on 10/3/2001. + ******************************************************************************* * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -563,6 +588,7 @@ initialize_server_options(&options); /* Parse command-line arguments. */ + /* SD Mod: add s option to getopt() call */ while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:dDeiqtQ46")) != -1) { switch (opt) { case '4': @@ -645,6 +671,14 @@ case 'u': utmp_len = atoi(optarg); break; + /* + * Begin SD Mod: Add option to handle option to turn off + * steno timing manipulation. + */ + case 'S': + options.use_steno_timing_manipulation = 0; + break; + /* End SD Mod */ case '?': default: fprintf(stderr, "sshd version %s\n", SSH_VERSION); @@ -665,6 +699,9 @@ fprintf(stderr, " -u len Maximum hostname length for utmp recording\n"); fprintf(stderr, " -4 Use IPv4 only\n"); fprintf(stderr, " -6 Use IPv6 only\n"); + /* SD Mod */ + fprintf(stderr, " -S Don't use stenographic timing manipulation\n"); + exit(1); } }