[tor-commits] [torspec/master] Add mikeperry's padding negotiation proposal and give it a number.

isis at torproject.org isis at torproject.org
Fri Sep 25 11:42:21 UTC 2015


commit 91e207e91d0375273004ecf16364c073e3e82043
Author: Isis Lovecruft <isis at torproject.org>
Date:   Fri Sep 25 11:40:28 2015 +0000

    Add mikeperry's padding negotiation proposal and give it a number.
---
 proposals/000-index.txt               |    2 +
 proposals/254-padding-negotiation.txt |  628 +++++++++++++++++++++++++++++++++
 proposals/proposal-status.txt         |    6 +
 proposals/xxx-padding-negotiation.txt |  628 ---------------------------------
 4 files changed, 636 insertions(+), 628 deletions(-)

diff --git a/proposals/000-index.txt b/proposals/000-index.txt
index 0460e87..c1f42e2 100644
--- a/proposals/000-index.txt
+++ b/proposals/000-index.txt
@@ -174,6 +174,7 @@ Proposals by number:
 251  Padding for netflow record resolution reduction [DRAFT]
 252  Single Onion Services [DRAFT]
 253  Out of Band Circuit HMACs [DRAFT]
+254  Padding Negotiation [DRAFT]
 
 
 Proposals by status:
@@ -195,6 +196,7 @@ Proposals by status:
    251  Padding for netflow record resolution reduction
    252  Single Onion Services
    253  Out of Band Circuit HMACs
+   254  Padding Negotiation
  NEEDS-REVISION:
    190  Bridge Client Authorization Based on a Shared Secret
  OPEN:
diff --git a/proposals/254-padding-negotiation.txt b/proposals/254-padding-negotiation.txt
new file mode 100644
index 0000000..e4da004
--- /dev/null
+++ b/proposals/254-padding-negotiation.txt
@@ -0,0 +1,628 @@
+Filename: 254-padding-negotiation.txt
+Title: Padding Negotiation
+Authors: Mike Perry
+Created: 01 September 2015
+Status: Draft
+
+
+0. Overview
+
+This proposal aims to describe mechanisms for requesting various types
+of padding from relays.
+
+These padding primitives are general enough to use to defend against
+both website traffic fingerprinting as well as hidden service circuit
+setup fingerprinting.
+
+
+1. Motivation
+
+Tor already supports both link-level padding via (CELL_PADDING cell
+types), as well as circuit-level padding (via RELAY_COMMAND_DROP relay
+cells).
+
+Unfortunately, there is no way for clients to request padding from
+relays, or request that relays not send them padding to conserve
+bandwidth. This proposal aims to create a mechanism for clients to do
+both of these.
+
+It also establishes consensus parameters to limit the amount of padding
+that relays will send, to prevent custom wingnut clients from requesting
+too much.
+
+
+2. Link-level padding
+
+Padding is most useful if it can defend against a malicious or
+compromised guard node. However, link-level padding is still useful to
+defend against an adversary that can merely observe a Guard node
+externally, such as for low-resolution netflow-based attacks (see
+Proposal 251[1]).
+
+In that scenario, the primary negotiation mechanism we need is a way for
+mobile clients to tell their Guards to stop padding, or to pad less
+often. The following Trunnel payloads should cover the needed
+parameters:
+
+    const CELL_PADDING_COMMAND_STOP = 1;
+    const CELL_PADDING_COMMAND_START = 2;
+
+    /* This command tells the relay to stop sending any periodic
+       CELL_PADDING cells. */
+    struct cell_padding_stop {
+      u8 command IN [CELL_PADDING_COMMAND_STOP];
+    };
+
+    /* This command tells the relay to alter its min and max netflow
+       timeout range values, and send padding at that rate (resuming
+       if stopped). */
+    struct cell_padding_start {
+      u8 command IN [CELL_PADDING_COMMAND_START];
+
+      /* Min must not be lower than the current consensus parameter
+         nf_ito_low. */
+      u16 ito_low_ms;
+
+      /* Max must not be lower than ito_low_ms */
+      u16 ito_high_ms;
+    };
+
+More complicated forms of link-level padding can still be specified
+using the primitives in Section 3, by using "leaky pipe" topology to
+send the RELAY commands to the Guard node instead of to later nodes in
+the circuit.
+
+
+3. End-to-end circuit padding
+
+For circuit-level padding, we need two types of additional features: the
+ability to schedule additional incoming cells at one or more fixed
+points in the future, and the ability to schedule a statistical
+distribution of arbitrary padding to overlay on top of non-padding
+traffic (aka "Adaptive Padding").
+
+In both cases, these messages will be sent from clients to middle nodes
+using the "leaky pipe" property of the 'recognized' field of RELAY
+cells, allowing padding to originate from middle nodes on a circuit in a
+way that is not detectable from the Guard node.
+
+This same mechanism can also be used to request padding from the Guard
+node itself, to achieve link-level padding without the additional
+overhead requirements on middle nodes.
+
+3.1. Fixed-schedule padding message (RELAY_COMMAND_PADDING_SCHEDULE)
+
+The fixed schedule padding will be encoded in a
+RELAY_COMMAND_PADDING_SCHEDULE cell. It specifies a set of up to 80
+fixed time points in the future to send cells.
+
+XXX: 80 timers is a lot to allow every client to create. We may want to
+have something that checks this structure to ensure it actually
+schedules no more than N in practice, until we figure out how to
+optimize either libevent or timer scheduling/packet delivery. See also
+Section 4.3.
+
+The RELAY_COMMAND_PADDING_SCHEDULE body is specified in Trunnel as
+follows:
+
+    struct relay_padding_schedule {
+       u8 schedule_length IN [1..80];
+
+       /* Number of microseconds before sending cells (cumulative) */
+       u32 when_send[schedule_length];
+
+       /* Number of cells to send at time point sum(when_send[0..i]) */
+       u16 num_cells[schedule_length];
+
+       /* Adaptivity: If 1, and server-originating cells arrive before the
+          next when_send time, then decrement the next non-zero when_send
+          index, so we don't send a padding cell then, too */
+       u8 adaptive IN [0,1];
+    };
+
+To allow both high-resolution time values, and the ability to specify
+timeout values far in the future, the time values are cumulative. In
+other words, sending a cell with when_send = [MAX_INT, MAX_INT, MAX_INT,
+0...] and num_cells = [0, 0, 100, 0...] would cause the relay to reply
+with 100 cells in 3*MAX_INT microseconds from the receipt of this cell.
+
+This scheduled padding is non-periodic. For any forms of periodic
+padding, implementations should use the RELAY_COMMAND_PADDING_ADAPTIVE
+cell from Section 3.2 instead.
+
+3.2. Adaptive Padding message (RELAY_COMMAND_PADDING_ADAPTIVE)
+
+The following message is a generalization of the Adaptive Padding
+defense specified in "Timing Attacks and Defenses"[2].
+
+The message encodes either one or two state machines, each of which can
+contain one or two histograms ("Burst" and "Gap") governing their
+behavior.
+
+The "Burst" histogram specifies the delay probabilities for sending a
+padding packet after the arrival of a non-padding data packet.
+
+The "Gap" histogram specifies the delay probabilities for sending
+another padding packet after a padding packet was just sent from this
+node. This self-triggering property of the "Gap" histogram allows the
+construction of multi-packet padding trains using a simple statistical
+distribution.
+
+Both "Gap" and "Burst" histograms each have a special "Infinity" bin,
+which means "We have decided not to send a packet".
+
+Each histogram is combined with state transition information, which
+allows a client to specify the types of incoming packets that cause the
+state machine to decide to schedule padding cells (and/or when to cease
+scheduling them).
+
+The client also maintains its own local histogram state machine(s), for
+reacting to traffic on its end.
+
+Note that our generalization of the Adaptive Padding state machine also
+gives clients full control over the state transition events, even
+allowing them to specify a single-state Burst-only state machine if
+desired. See Sections 3.2.1 and 3.2.2 for details.
+
+The histograms and the associated state machine packet layout is
+specified in Trunnel as follows:
+
+    /* These constants form a bitfield to specify the types of events
+     * that can cause transitions between state machine states.
+     *
+     * Note that SENT and RECV are relative to this endpoint. For
+     * relays, SENT means packets destined towards the client and
+     * RECV means packets destined towards the relay. On the client,
+     * SENT means packets destined towards the relay, where as RECV
+     * means packets destined towards the client.
+     */
+    const RELAY_PADDING_TRANSITION_EVENT_NONPADDING_RECV = 1;
+    const RELAY_PADDING_TRANSITION_EVENT_NONPADDING_SENT = 2;
+    const RELAY_PADDING_TRANSITION_EVENT_PADDING_SENT = 4;
+    const RELAY_PADDING_TRANSITION_EVENT_PADDING_RECV = 8;
+    const RELAY_PADDING_TRANSITION_EVENT_INFINITY = 16;
+    const RELAY_PADDING_TRANSITION_EVENT_BINS_EMPTY = 32;
+
+    /* Token Removal rules. Enum, not bitfield. */
+    const RELAY_PADDING_REMOVE_NO_TOKENS = 0;
+    const RELAY_PADDING_REMOVE_LOWER_TOKENS = 1;
+    const RELAY_PADDING_REMOVE_HIGHER_TOKENS = 2;
+    const RELAY_PADDING_REMOVE_CLOSEST_TOKENS = 3;
+
+    /* This payload encodes a histogram delay distribution representing
+     * the probability of sending a single RELAY_DROP cell after a
+     * given delay in response to a non-padding cell.
+     *
+     * Payload max size: 113 bytes
+     */
+    struct burst_state {
+      u8 histogram_len IN [2..51];
+      u16 histogram[histogram_len];
+      u32 start_usec;
+      u16 max_sec;
+
+      /* This is a bitfield that specifies which direction and types
+       * of traffic that cause us to abort our scheduled packet and
+       * return to waiting for another event from transition_burst_events.
+       */
+      u8 transition_start_events;
+
+      /* This is a bitfield that specifies which direction and types
+       * of traffic that cause us to remain in the burst state: Cancel the
+       * pending padding packet (if any), and schedule another padding
+       * packet from our histogram.
+       */
+      u8 transition_reschedule_events;
+
+      /* This is a bitfield that specifies which direction and types
+       * of traffic that cause us to transition to the Gap state. */
+      u8 transition_gap_events;
+
+      /* If true, remove tokens from the histogram upon padding and
+       * non-padding activity. */
+      u8 remove_tokens IN [0..3];
+    };
+
+    /* This histogram encodes a delay distribution representing the
+     * probability of sending a single additional padding packet after
+     * sending a padding packet that originated at this hop.
+     *
+     * Payload max size: 113 bytes
+     */
+    struct gap_state {
+      u8 histogram_len IN [2..51];
+      u16 histogram[histogram_len];
+      u32 start_usec;
+      u16 max_sec;
+
+      /* This is a bitfield which specifies which direction and types
+       * of traffic should cause us to transition back to the start
+       * state (ie: abort scheduling packets completely). */
+      u8 transition_start_events;
+
+      /* This is a bitfield which specifies which direction and types
+       * of traffic should cause us to transition back to the burst
+       * state (and schedule a packet from the burst histogram). */
+      u8 transition_burst_events;
+
+      /* This is a bitfield that specifies which direction and types
+       * of traffic that cause us to remain in the gap state: Cancel the
+       * pending padding packet (if any), and schedule another padding
+       * packet from our histogram.
+       */
+      u8 transition_reschedule_events;
+
+      /* If true, remove tokens from the histogram upon padding and
+         non-padding activity. */
+      u8 remove_tokens IN [0..3];
+    };
+
+    /* Payload max size: 227 bytes */
+    struct adaptive_padding_machine {
+      /* This is a bitfield which specifies which direction and types
+       * of traffic should cause us to transition to the burst
+       * state (and schedule a packet from the burst histogram). */
+       u8 transition_burst_events;
+
+       struct burst_state burst;
+       struct gap_state gap;
+    };
+
+    /* This is the full payload of a RELAY_COMMAND_PADDING_ADAPTIVE
+     * cell.
+     *
+     * Payload max size: 455 bytes
+     */
+    struct relay_command_padding_adaptive {
+       /* Technically, we could allow more than 2 state machines here,
+          but only two are sure to fit. More than 2 seems excessive
+          anyway. */
+       u8 num_machines IN [1,2];
+
+       struct adaptive_padding_machine machines[num_machines];
+    };
+
+3.2.1. Histogram state machine operation
+
+Each of pair of histograms ("Burst" and "Gap") together form a state
+machine whose transitions are governed by incoming traffic and/or
+locally generated padding traffic.
+
+Each state machine has a Start state S, a Burst state B, and a Gap state
+G.
+
+The state machine starts idle (state S) until it receives a packet of a
+type that matches the bitmask in machines[i].transition_burst_events. If
+machines[i].transition_burst_events is 0, transition to the burst state
+happens immediately.
+
+This causes it to enter burst mode (state B), in which a delay t is
+sampled from the Burst histogram, and a timer is scheduled to count down
+until either another matching packet arrives, or t expires. If the
+"Infinity" time is sampled from this histogram, the machine returns to
+the lowest state with the INFINITY event bit set.
+
+If a packet that matches machines[i].burst.transition_start_events
+arrives before t expires, the machine transitions back to the Start
+state.
+
+If a packet that matches machines[i].burst.transition_reschedule_events
+arrives before t expires, a new delay is sampled and the process is
+repeated again, i.e.  it remains in burst mode.
+
+Otherwise, if t expires, a padding message is sent to the other end.
+
+If a packet that matches machines[i].burst.transition_gap_events
+arrives (or is sent), the machine transitions to the Gap state G.
+
+In state G, the machine samples from the Gap histogram and sends padding
+messages when the time it samples expires. If an infinite delay is
+sampled while being in state G we jump back to state B or S,
+depending upon the usage of the infinity event bitmask.
+
+If a packet arrives that matches gap.transition_start_events, the
+machine transitions back to the Start state.
+
+If a packet arrives that matches gap.transition_burst_events, the
+machine transitions back to the Burst state.
+
+If a packet arrives that matches
+machines[i].gap.transition_reschedule_events, the machine remains in G
+but schedules a new padding time from its Gap histogram.
+
+In the event that a malicious or buggy client specifies conflicting
+state transition rules with the same bits in multiple transition
+bitmasks, the transition rules of a state that specify transition to
+earlier states take priority. So burst.transition_start_events
+takes priority over burst.transition_reschedule_events, and both of
+these take priority over burst.transition_gap_events.
+
+Similarly, gap.transition_start_events takes priority over
+gap.transition_burst_events, and gap.transition_burst_events takes
+priority over gap.transition_reschedule_events.
+
+In our generalization of Adaptive Padding, either histogram may actually
+be self-scheduling (by setting the bit
+RELAY_PADDING_TRANSITION_EVENT_PADDING_SENT in their
+transition_reschedule_events). This allows the client to create a
+single-state machine if desired.
+
+Clients are expected to maintain their own local version of the state
+machines, for reacting to their own locally generated traffic, in
+addition to sending one or more state machines to the middle relay. The
+histograms that the client uses locally will differ from the ones it
+sends to the upstream relay.
+
+On the client, the "SENT" direction means packets destined towards the
+relay, where as "RECV" means packets destined towards the client.
+However, on the relay, the "SENT" direction means packets destined
+towards the client, where as "RECV" means packets destined towards the
+relay.
+
+3.2.2. The original Adaptive Padding algorithm
+
+As we have noted, the state machines above represent a generalization of
+the original Adaptive Padding algorithm. To implement the original
+behavior, the following flags should be set in both the client and
+the relay state machines:
+
+ num_machines = 1;
+
+ machines[0].transition_burst_events =
+    RELAY_PADDING_TRANSITION_EVENT_NONPADDING_SENT;
+
+ machines[0].burst.transition_reschedule_events =
+    RELAY_PADDING_TRANSITION_EVENT_NONPADDING_SENT;
+
+ machines[0].burst.transition_gap_events =
+    RELAY_PADDING_TRANSITION_EVENT_PADDING_SENT;
+
+ machines[0].burst.transition_start_events =
+    RELAY_PADDING_TRANSITION_EVENT_INFINITY;
+
+ machines[0].gap.transition_reschedule_events =
+    RELAY_PADDING_TRANSITION_EVENT_PADDING_SENT;
+
+ machines[0].gap.transition_burst_events =
+    RELAY_PADDING_TRANSITION_EVENT_NONPADDING_SENT |
+    RELAY_PADDING_TRANSITION_EVENT_INFINITY;
+
+The rest of the transition fields would be 0.
+
+Adding additional transition flags will either increase or decrease the
+amount of padding sent, depending on their placement.
+
+The second machine slot is provided in the event that it proves useful
+to have separate state machines reacting to both sent and received
+traffic.
+
+3.2.3. Histogram decoding/representation
+
+Each of the histograms' fields represent a probability distribution that
+is expanded into bins representing time periods a[i]..b[i] as follows:
+
+start_usec,max_sec,histogram_len initialized from appropriate histogram
+body.
+
+n = histogram_len-1
+INFINITY_BIN = n
+
+a[0] = start_usec;
+b[0] = start_usec + max_sec*USEC_PER_SEC/2^(n-1);
+for(i=1; i < n; i++) {
+  a[i] = start_usec + max_sec*USEC_PER_SEC/2^(n-i)
+  b[i] = start_usec + max_sec*USEC_PER_SEC/2^(n-i-1)
+}
+
+To sample the delay time to send a padding packet, perform the
+following:
+
+  i = 0;
+  curr_weight = histogram[0];
+
+  tot_weight = sum(histogram);
+  bin_choice = crypto_rand_int(tot_weight);
+
+  while (curr_weight < bin_choice) {
+    curr_weight += histogram[i];
+    i++;
+  }
+
+  if (i == INFINITY_BIN)
+    return; // Don't send a padding packet
+
+  // Sample uniformly between a[i] and b[i]
+  send_padding_packet_at = a[i] + crypto_rand_int(b[i] - a[i]);
+
+In this way, the bin widths are exponentially increasing in width, where
+the width is set at max_sec/2^(n-i) seconds. This exponentially
+increasing bin width allows the histograms to most accurately represent
+small interpacket delay (where accuracy is needed), and devote less
+accuracy to larger timescales (where accuracy is not as important).
+
+3.2.4. Token removal and refill
+
+If the remove_tokens field is set to a non-zero value for a given
+state's histogram, then whenever a padding packet is sent, the
+corresponding histogram bin's token count is decremented by one.
+
+If a packet matching the current state's transition_reschedule_events
+bitmask arrives from the server before the chosen padding timer expires,
+then a token is removed from a non-empty bin corresponding to
+the delay since the last packet was sent, and the padding packet timer
+is re-sampled from the histogram.
+
+The three enums for the remove_tokens field govern if we take the token
+out of the nearest lower non-empty bin, the nearest higher non-empty
+bin, or simply the closest non-empty bin.
+
+If the entire histogram becomes empty, it is then refilled to the
+original values. This refill happens prior to any state transitions due
+to RELAY_PADDING_TRANSITION_EVENT_BINS_EMPTY (but obviously does not
+prevent the transition from happening).
+
+
+3.2.5. Constructing the histograms
+
+Care must be taken when constructing the histograms themselves, since
+their non-uniform widths means that the actual underlying probability
+distribution needs to be both normalized for total number of tokens, as
+well as the non-uniform histogram bin widths.
+
+Care should also be taken with interaction with the token removal rules
+from Section 3.2.4. Obviously using a large number of tokens will cause
+token removal to have much less of an impact upon the adaptive nature of
+the padding in the face of existing traffic.
+
+Actual optimal histogram and state transition construction for different
+traffic types is expected to be a topic for further research.
+
+Intuitively, the burst state is used to detect when the line is idle
+(and should therefore have few or no tokens in low histogram bins). The
+lack of tokens in the low histogram bins causes the system to remain in
+the burst state until the actual application traffic either slows,
+stalls, or has a gap.
+
+The gap state is used to fill in otherwise idle periods with artificial
+payloads from the server (and should have many tokens in low bins, and
+possibly some also at higher bins).
+
+It should be noted that due to our generalization of these states and
+their transition possibilities, more complicated interactions are also
+possible.
+
+
+4. Security considerations and mitigations
+
+The risks from this proposal are primarily DoS/resource exhaustion, and
+side channels.
+
+4.1. Rate limiting and accounting
+
+Fully client-requested padding introduces a vector for resource
+amplification attacks and general network overload due to
+overly-aggressive client implementations requesting too much padding.
+
+Current research indicates that this form of statistical padding should
+be effective at overhead rates of 50-60%. This suggests that clients
+that use more padding than this are likely to be overly aggressive in
+their behavior.
+
+We recommend that three consensus parameters be used in the event that
+the network is being overloaded from padding to such a degree that
+padding requests should be ignored:
+
+  * CircuitPaddingMaxRatio
+    - The maximum ratio of padding traffic to non-padding traffic
+      (expressed as a percent) to allow on a circuit before ceasing
+      to pad. Ex: 75 means 75 padding packets for every 100 non-padding
+      packets.
+    - Default: 120
+  * CircuitPaddingLimitCount
+    - The number of padding cells that must be transmitted before the
+      ratio limit is applied.
+    - Default: 5000
+  * CircuitPaddingLimitTime
+    - The time period in seconds over which to count padding cells for
+      application of the ratio limit (ie: reset the limit count this
+      often).
+    - Default: 60
+
+XXX: Should we cap padding at these rates, or fully disable it once
+they're crossed? Probably cap?
+
+In order to monitor the quantity of padding to decide if we should alter
+these limits in the consensus, every node will publish the following
+values in a padding-counts line in its extra-info descriptor:
+
+ * write-drop-multihop
+   - The number of RELAY_DROP cells sent by this relay to a next hop
+     that is listed in the consensus.
+ * write-drop-onehop
+   - The number of RELAY_DROP cells sent by this relay to a next hop
+     that is not listed in the consensus.
+ * write-pad
+   - The number of CELL_PADDING cells sent by this relay.
+ * write-total
+   - The total number of cells sent by this relay.
+ * read-drop-multihop
+   - The number of RELAY_DROP cells read by this relay from a hop
+     that is listed in the consensus.
+ * read-drop-onehop
+   - The number of RELAY_DROP cells read by this relay from a hop
+     that is not listed in the consensus.
+ * read-pad
+   - The number of CELL_PADDING cells read by this relay.
+ * read-total
+   - The total number of cells read by this relay.
+
+Each of these counters will be rounded to the nearest 10,000 cells. This
+rounding parameter will also be listed in the extra-info descriptor line, in
+case we change it in a later release.
+
+In the future, we may decide to introduce Laplace Noise in a similar
+manner to the hidden service statistics, to further obscure padding
+quantities.
+
+4.2. Malicious state machines
+
+The state machine capabilities of RELAY_COMMAND_PADDING_ADAPTIVE are
+very flexible, and as a result may specify conflicting or
+non-deterministic state transitions.
+
+We believe that the rules in Section 3.2.1 for prioritizing transitions
+towards lower states remove any possibility of non-deterministic
+transitions.
+
+However, because of self-triggering property that allows the state
+machines to schedule more padding packets after sending their own
+locally generated padding packets, care must be taken with the
+interaction with the rate limiting rules in Section 4.1. If the limits
+in section 4.1 are exceeded, the state machines should stop, rather than
+continually poll themselves trying to transmit packets and being blocked
+by the rate limiter at another layer.
+
+4.3. Libevent timer exhaustion
+
+As mentioned in section 3.1, scheduled padding may create an excessive
+number of libevent timers. Care should be taken in the implementation to
+devise a way to prevent clients from sending padding requests
+specifically designed to impact the ability of relays to function by
+causing too many timers to be scheduled at once.
+
+XXX: Can we suggest any specifics here? I can imagine a few ways of
+lazily scheduling timers only when they are close to their expiry time,
+and other ways of minimizing the number of pending timer callbacks at a
+given time, but I am not sure which would be best for libevent.
+
+4.4. Side channels
+
+In order to prevent relays from introducing side channels by requesting
+padding from clients, all of these commands should only be valid in the
+outgoing (from the client/OP) direction.
+
+Clients should perform accounting on the amount of padding that they
+receive, and if it exceeds the amount that they have requested, they
+alert the user of a potentially misbehaving node, and/or close the
+circuit.
+
+Similarly, if RELAY_DROP cells arrive from the last hop of a circuit,
+rather than from the expected interior node, clients should alert the
+user of the possibility of that circuit endpoint introducing a
+side-channel attack, and/or close the circuit.
+
+4.5. Memory exhaustion
+
+Because interior nodes do not have information on the current circuits
+SENDME windows, it is possible for malicious clients to consume the
+buffers of relays by specifying padding, and then not reading from the
+associated circuits.
+
+XXX: Tor already had a few flow-control related DoS's in the past[3]. Is
+that defense sufficient here without any mods? It seems like it may be!
+
+-------------------
+
+1. https://gitweb.torproject.org/torspec.git/tree/proposals/251-netflow-padding.txt
+2. http://freehaven.net/anonbib/cache/ShWa-Timing06.pdf
+3. https://blog.torproject.org/blog/new-tor-denial-service-attacks-and-defenses
diff --git a/proposals/proposal-status.txt b/proposals/proposal-status.txt
index 6ca1bda..36627b7 100644
--- a/proposals/proposal-status.txt
+++ b/proposals/proposal-status.txt
@@ -441,3 +441,9 @@ again to remind me!
      circuit point-to-point so as to better resist or detect some kinds
      of tagging attacks. (9/2015)
 
+254  Padding Negotiation [DRAFT]
+
+     Describes general mechanisms and new cells/commands for requesting
+     various types of padding between clients and relays, for use in defending
+     against both website traffic fingerprinting as well as hidden service
+     circuit setup fingerprinting. (9/2015)
diff --git a/proposals/xxx-padding-negotiation.txt b/proposals/xxx-padding-negotiation.txt
deleted file mode 100644
index a42bd6c..0000000
--- a/proposals/xxx-padding-negotiation.txt
+++ /dev/null
@@ -1,628 +0,0 @@
-Filename: xxx-padding-negotiation.txt
-Title: Padding Negotiation
-Authors: Mike Perry
-Created: 01 September 2015
-Status: Draft
-
-
-0. Overview
-
-This proposal aims to describe mechanisms for requesting various types
-of padding from relays.
-
-These padding primitives are general enough to use to defend against
-both website traffic fingerprinting as well as hidden service circuit
-setup fingerprinting.
-
-
-1. Motivation
-
-Tor already supports both link-level padding via (CELL_PADDING cell
-types), as well as circuit-level padding (via RELAY_COMMAND_DROP relay
-cells).
-
-Unfortunately, there is no way for clients to request padding from
-relays, or request that relays not send them padding to conserve
-bandwidth. This proposal aims to create a mechanism for clients to do
-both of these.
-
-It also establishes consensus parameters to limit the amount of padding
-that relays will send, to prevent custom wingnut clients from requesting
-too much.
-
-
-2. Link-level padding
-
-Padding is most useful if it can defend against a malicious or
-compromised guard node. However, link-level padding is still useful to
-defend against an adversary that can merely observe a Guard node
-externally, such as for low-resolution netflow-based attacks (see
-Proposal 251[1]).
-
-In that scenario, the primary negotiation mechanism we need is a way for
-mobile clients to tell their Guards to stop padding, or to pad less
-often. The following Trunnel payloads should cover the needed
-parameters:
-
-    const CELL_PADDING_COMMAND_STOP = 1;
-    const CELL_PADDING_COMMAND_START = 2;
-
-    /* This command tells the relay to stop sending any periodic
-       CELL_PADDING cells. */
-    struct cell_padding_stop {
-      u8 command IN [CELL_PADDING_COMMAND_STOP];
-    };
-
-    /* This command tells the relay to alter its min and max netflow
-       timeout range values, and send padding at that rate (resuming
-       if stopped). */
-    struct cell_padding_start {
-      u8 command IN [CELL_PADDING_COMMAND_START];
-
-      /* Min must not be lower than the current consensus parameter
-         nf_ito_low. */
-      u16 ito_low_ms;
-
-      /* Max must not be lower than ito_low_ms */
-      u16 ito_high_ms;
-    };
-
-More complicated forms of link-level padding can still be specified
-using the primitives in Section 3, by using "leaky pipe" topology to
-send the RELAY commands to the Guard node instead of to later nodes in
-the circuit.
-
-
-3. End-to-end circuit padding
-
-For circuit-level padding, we need two types of additional features: the
-ability to schedule additional incoming cells at one or more fixed
-points in the future, and the ability to schedule a statistical
-distribution of arbitrary padding to overlay on top of non-padding
-traffic (aka "Adaptive Padding").
-
-In both cases, these messages will be sent from clients to middle nodes
-using the "leaky pipe" property of the 'recognized' field of RELAY
-cells, allowing padding to originate from middle nodes on a circuit in a
-way that is not detectable from the Guard node.
-
-This same mechanism can also be used to request padding from the Guard
-node itself, to achieve link-level padding without the additional
-overhead requirements on middle nodes.
-
-3.1. Fixed-schedule padding message (RELAY_COMMAND_PADDING_SCHEDULE)
-
-The fixed schedule padding will be encoded in a
-RELAY_COMMAND_PADDING_SCHEDULE cell. It specifies a set of up to 80
-fixed time points in the future to send cells.
-
-XXX: 80 timers is a lot to allow every client to create. We may want to
-have something that checks this structure to ensure it actually
-schedules no more than N in practice, until we figure out how to
-optimize either libevent or timer scheduling/packet delivery. See also
-Section 4.3.
-
-The RELAY_COMMAND_PADDING_SCHEDULE body is specified in Trunnel as
-follows:
-
-    struct relay_padding_schedule {
-       u8 schedule_length IN [1..80];
-
-       /* Number of microseconds before sending cells (cumulative) */
-       u32 when_send[schedule_length];
-
-       /* Number of cells to send at time point sum(when_send[0..i]) */
-       u16 num_cells[schedule_length];
-
-       /* Adaptivity: If 1, and server-originating cells arrive before the
-          next when_send time, then decrement the next non-zero when_send
-          index, so we don't send a padding cell then, too */
-       u8 adaptive IN [0,1];
-    };
-
-To allow both high-resolution time values, and the ability to specify
-timeout values far in the future, the time values are cumulative. In
-other words, sending a cell with when_send = [MAX_INT, MAX_INT, MAX_INT,
-0...] and num_cells = [0, 0, 100, 0...] would cause the relay to reply
-with 100 cells in 3*MAX_INT microseconds from the receipt of this cell.
-
-This scheduled padding is non-periodic. For any forms of periodic
-padding, implementations should use the RELAY_COMMAND_PADDING_ADAPTIVE
-cell from Section 3.2 instead.
-
-3.2. Adaptive Padding message (RELAY_COMMAND_PADDING_ADAPTIVE)
-
-The following message is a generalization of the Adaptive Padding
-defense specified in "Timing Attacks and Defenses"[2].
-
-The message encodes either one or two state machines, each of which can
-contain one or two histograms ("Burst" and "Gap") governing their
-behavior.
-
-The "Burst" histogram specifies the delay probabilities for sending a
-padding packet after the arrival of a non-padding data packet.
-
-The "Gap" histogram specifies the delay probabilities for sending
-another padding packet after a padding packet was just sent from this
-node. This self-triggering property of the "Gap" histogram allows the
-construction of multi-packet padding trains using a simple statistical
-distribution.
-
-Both "Gap" and "Burst" histograms each have a special "Infinity" bin,
-which means "We have decided not to send a packet".
-
-Each histogram is combined with state transition information, which
-allows a client to specify the types of incoming packets that cause the
-state machine to decide to schedule padding cells (and/or when to cease
-scheduling them).
-
-The client also maintains its own local histogram state machine(s), for
-reacting to traffic on its end.
-
-Note that our generalization of the Adaptive Padding state machine also
-gives clients full control over the state transition events, even
-allowing them to specify a single-state Burst-only state machine if
-desired. See Sections 3.2.1 and 3.2.2 for details.
-
-The histograms and the associated state machine packet layout is
-specified in Trunnel as follows:
-
-    /* These constants form a bitfield to specify the types of events
-     * that can cause transitions between state machine states.
-     *
-     * Note that SENT and RECV are relative to this endpoint. For
-     * relays, SENT means packets destined towards the client and
-     * RECV means packets destined towards the relay. On the client,
-     * SENT means packets destined towards the relay, where as RECV
-     * means packets destined towards the client.
-     */
-    const RELAY_PADDING_TRANSITION_EVENT_NONPADDING_RECV = 1;
-    const RELAY_PADDING_TRANSITION_EVENT_NONPADDING_SENT = 2;
-    const RELAY_PADDING_TRANSITION_EVENT_PADDING_SENT = 4;
-    const RELAY_PADDING_TRANSITION_EVENT_PADDING_RECV = 8;
-    const RELAY_PADDING_TRANSITION_EVENT_INFINITY = 16;
-    const RELAY_PADDING_TRANSITION_EVENT_BINS_EMPTY = 32;
-
-    /* Token Removal rules. Enum, not bitfield. */
-    const RELAY_PADDING_REMOVE_NO_TOKENS = 0;
-    const RELAY_PADDING_REMOVE_LOWER_TOKENS = 1;
-    const RELAY_PADDING_REMOVE_HIGHER_TOKENS = 2;
-    const RELAY_PADDING_REMOVE_CLOSEST_TOKENS = 3;
-
-    /* This payload encodes a histogram delay distribution representing
-     * the probability of sending a single RELAY_DROP cell after a
-     * given delay in response to a non-padding cell.
-     *
-     * Payload max size: 113 bytes
-     */
-    struct burst_state {
-      u8 histogram_len IN [2..51];
-      u16 histogram[histogram_len];
-      u32 start_usec;
-      u16 max_sec;
-
-      /* This is a bitfield that specifies which direction and types
-       * of traffic that cause us to abort our scheduled packet and
-       * return to waiting for another event from transition_burst_events.
-       */
-      u8 transition_start_events;
-
-      /* This is a bitfield that specifies which direction and types
-       * of traffic that cause us to remain in the burst state: Cancel the
-       * pending padding packet (if any), and schedule another padding
-       * packet from our histogram.
-       */
-      u8 transition_reschedule_events;
-
-      /* This is a bitfield that specifies which direction and types
-       * of traffic that cause us to transition to the Gap state. */
-      u8 transition_gap_events;
-
-      /* If true, remove tokens from the histogram upon padding and
-       * non-padding activity. */
-      u8 remove_tokens IN [0..3];
-    };
-
-    /* This histogram encodes a delay distribution representing the
-     * probability of sending a single additional padding packet after
-     * sending a padding packet that originated at this hop.
-     *
-     * Payload max size: 113 bytes
-     */
-    struct gap_state {
-      u8 histogram_len IN [2..51];
-      u16 histogram[histogram_len];
-      u32 start_usec;
-      u16 max_sec;
-
-      /* This is a bitfield which specifies which direction and types
-       * of traffic should cause us to transition back to the start
-       * state (ie: abort scheduling packets completely). */
-      u8 transition_start_events;
-
-      /* This is a bitfield which specifies which direction and types
-       * of traffic should cause us to transition back to the burst
-       * state (and schedule a packet from the burst histogram). */
-      u8 transition_burst_events;
-
-      /* This is a bitfield that specifies which direction and types
-       * of traffic that cause us to remain in the gap state: Cancel the
-       * pending padding packet (if any), and schedule another padding
-       * packet from our histogram.
-       */
-      u8 transition_reschedule_events;
-
-      /* If true, remove tokens from the histogram upon padding and
-         non-padding activity. */
-      u8 remove_tokens IN [0..3];
-    };
-
-    /* Payload max size: 227 bytes */
-    struct adaptive_padding_machine {
-      /* This is a bitfield which specifies which direction and types
-       * of traffic should cause us to transition to the burst
-       * state (and schedule a packet from the burst histogram). */
-       u8 transition_burst_events;
-
-       struct burst_state burst;
-       struct gap_state gap;
-    };
-
-    /* This is the full payload of a RELAY_COMMAND_PADDING_ADAPTIVE
-     * cell.
-     *
-     * Payload max size: 455 bytes
-     */
-    struct relay_command_padding_adaptive {
-       /* Technically, we could allow more than 2 state machines here,
-          but only two are sure to fit. More than 2 seems excessive
-          anyway. */
-       u8 num_machines IN [1,2];
-
-       struct adaptive_padding_machine machines[num_machines];
-    };
-
-3.2.1. Histogram state machine operation
-
-Each of pair of histograms ("Burst" and "Gap") together form a state
-machine whose transitions are governed by incoming traffic and/or
-locally generated padding traffic.
-
-Each state machine has a Start state S, a Burst state B, and a Gap state
-G.
-
-The state machine starts idle (state S) until it receives a packet of a
-type that matches the bitmask in machines[i].transition_burst_events. If
-machines[i].transition_burst_events is 0, transition to the burst state
-happens immediately.
-
-This causes it to enter burst mode (state B), in which a delay t is
-sampled from the Burst histogram, and a timer is scheduled to count down
-until either another matching packet arrives, or t expires. If the
-"Infinity" time is sampled from this histogram, the machine returns to
-the lowest state with the INFINITY event bit set.
-
-If a packet that matches machines[i].burst.transition_start_events
-arrives before t expires, the machine transitions back to the Start
-state.
-
-If a packet that matches machines[i].burst.transition_reschedule_events
-arrives before t expires, a new delay is sampled and the process is
-repeated again, i.e.  it remains in burst mode.
-
-Otherwise, if t expires, a padding message is sent to the other end.
-
-If a packet that matches machines[i].burst.transition_gap_events
-arrives (or is sent), the machine transitions to the Gap state G.
-
-In state G, the machine samples from the Gap histogram and sends padding
-messages when the time it samples expires. If an infinite delay is
-sampled while being in state G we jump back to state B or S,
-depending upon the usage of the infinity event bitmask.
-
-If a packet arrives that matches gap.transition_start_events, the
-machine transitions back to the Start state.
-
-If a packet arrives that matches gap.transition_burst_events, the
-machine transitions back to the Burst state.
-
-If a packet arrives that matches
-machines[i].gap.transition_reschedule_events, the machine remains in G
-but schedules a new padding time from its Gap histogram.
-
-In the event that a malicious or buggy client specifies conflicting
-state transition rules with the same bits in multiple transition
-bitmasks, the transition rules of a state that specify transition to
-earlier states take priority. So burst.transition_start_events
-takes priority over burst.transition_reschedule_events, and both of
-these take priority over burst.transition_gap_events.
-
-Similarly, gap.transition_start_events takes priority over
-gap.transition_burst_events, and gap.transition_burst_events takes
-priority over gap.transition_reschedule_events.
-
-In our generalization of Adaptive Padding, either histogram may actually
-be self-scheduling (by setting the bit
-RELAY_PADDING_TRANSITION_EVENT_PADDING_SENT in their
-transition_reschedule_events). This allows the client to create a
-single-state machine if desired.
-
-Clients are expected to maintain their own local version of the state
-machines, for reacting to their own locally generated traffic, in
-addition to sending one or more state machines to the middle relay. The
-histograms that the client uses locally will differ from the ones it
-sends to the upstream relay.
-
-On the client, the "SENT" direction means packets destined towards the
-relay, where as "RECV" means packets destined towards the client.
-However, on the relay, the "SENT" direction means packets destined
-towards the client, where as "RECV" means packets destined towards the
-relay.
-
-3.2.2. The original Adaptive Padding algorithm
-
-As we have noted, the state machines above represent a generalization of
-the original Adaptive Padding algorithm. To implement the original
-behavior, the following flags should be set in both the client and
-the relay state machines:
-
- num_machines = 1;
-
- machines[0].transition_burst_events =
-    RELAY_PADDING_TRANSITION_EVENT_NONPADDING_SENT;
-
- machines[0].burst.transition_reschedule_events =
-    RELAY_PADDING_TRANSITION_EVENT_NONPADDING_SENT;
-
- machines[0].burst.transition_gap_events =
-    RELAY_PADDING_TRANSITION_EVENT_PADDING_SENT;
-
- machines[0].burst.transition_start_events =
-    RELAY_PADDING_TRANSITION_EVENT_INFINITY;
-
- machines[0].gap.transition_reschedule_events =
-    RELAY_PADDING_TRANSITION_EVENT_PADDING_SENT;
-
- machines[0].gap.transition_burst_events =
-    RELAY_PADDING_TRANSITION_EVENT_NONPADDING_SENT |
-    RELAY_PADDING_TRANSITION_EVENT_INFINITY;
-
-The rest of the transition fields would be 0.
-
-Adding additional transition flags will either increase or decrease the
-amount of padding sent, depending on their placement.
-
-The second machine slot is provided in the event that it proves useful
-to have separate state machines reacting to both sent and received
-traffic.
-
-3.2.3. Histogram decoding/representation
-
-Each of the histograms' fields represent a probability distribution that
-is expanded into bins representing time periods a[i]..b[i] as follows:
-
-start_usec,max_sec,histogram_len initialized from appropriate histogram
-body.
-
-n = histogram_len-1
-INFINITY_BIN = n
-
-a[0] = start_usec;
-b[0] = start_usec + max_sec*USEC_PER_SEC/2^(n-1);
-for(i=1; i < n; i++) {
-  a[i] = start_usec + max_sec*USEC_PER_SEC/2^(n-i)
-  b[i] = start_usec + max_sec*USEC_PER_SEC/2^(n-i-1)
-}
-
-To sample the delay time to send a padding packet, perform the
-following:
-
-  i = 0;
-  curr_weight = histogram[0];
-
-  tot_weight = sum(histogram);
-  bin_choice = crypto_rand_int(tot_weight);
-
-  while (curr_weight < bin_choice) {
-    curr_weight += histogram[i];
-    i++;
-  }
-
-  if (i == INFINITY_BIN)
-    return; // Don't send a padding packet
-
-  // Sample uniformly between a[i] and b[i]
-  send_padding_packet_at = a[i] + crypto_rand_int(b[i] - a[i]);
-
-In this way, the bin widths are exponentially increasing in width, where
-the width is set at max_sec/2^(n-i) seconds. This exponentially
-increasing bin width allows the histograms to most accurately represent
-small interpacket delay (where accuracy is needed), and devote less
-accuracy to larger timescales (where accuracy is not as important).
-
-3.2.4. Token removal and refill
-
-If the remove_tokens field is set to a non-zero value for a given
-state's histogram, then whenever a padding packet is sent, the
-corresponding histogram bin's token count is decremented by one.
-
-If a packet matching the current state's transition_reschedule_events
-bitmask arrives from the server before the chosen padding timer expires,
-then a token is removed from a non-empty bin corresponding to
-the delay since the last packet was sent, and the padding packet timer
-is re-sampled from the histogram.
-
-The three enums for the remove_tokens field govern if we take the token
-out of the nearest lower non-empty bin, the nearest higher non-empty
-bin, or simply the closest non-empty bin.
-
-If the entire histogram becomes empty, it is then refilled to the
-original values. This refill happens prior to any state transitions due
-to RELAY_PADDING_TRANSITION_EVENT_BINS_EMPTY (but obviously does not
-prevent the transition from happening).
-
-
-3.2.5. Constructing the histograms
-
-Care must be taken when constructing the histograms themselves, since
-their non-uniform widths means that the actual underlying probability
-distribution needs to be both normalized for total number of tokens, as
-well as the non-uniform histogram bin widths.
-
-Care should also be taken with interaction with the token removal rules
-from Section 3.2.4. Obviously using a large number of tokens will cause
-token removal to have much less of an impact upon the adaptive nature of
-the padding in the face of existing traffic.
-
-Actual optimal histogram and state transition construction for different
-traffic types is expected to be a topic for further research.
-
-Intuitively, the burst state is used to detect when the line is idle
-(and should therefore have few or no tokens in low histogram bins). The
-lack of tokens in the low histogram bins causes the system to remain in
-the burst state until the actual application traffic either slows,
-stalls, or has a gap.
-
-The gap state is used to fill in otherwise idle periods with artificial
-payloads from the server (and should have many tokens in low bins, and
-possibly some also at higher bins).
-
-It should be noted that due to our generalization of these states and
-their transition possibilities, more complicated interactions are also
-possible.
-
-
-4. Security considerations and mitigations
-
-The risks from this proposal are primarily DoS/resource exhaustion, and
-side channels.
-
-4.1. Rate limiting and accounting
-
-Fully client-requested padding introduces a vector for resource
-amplification attacks and general network overload due to
-overly-aggressive client implementations requesting too much padding.
-
-Current research indicates that this form of statistical padding should
-be effective at overhead rates of 50-60%. This suggests that clients
-that use more padding than this are likely to be overly aggressive in
-their behavior.
-
-We recommend that three consensus parameters be used in the event that
-the network is being overloaded from padding to such a degree that
-padding requests should be ignored:
-
-  * CircuitPaddingMaxRatio
-    - The maximum ratio of padding traffic to non-padding traffic
-      (expressed as a percent) to allow on a circuit before ceasing
-      to pad. Ex: 75 means 75 padding packets for every 100 non-padding
-      packets.
-    - Default: 120
-  * CircuitPaddingLimitCount
-    - The number of padding cells that must be transmitted before the
-      ratio limit is applied.
-    - Default: 5000
-  * CircuitPaddingLimitTime
-    - The time period in seconds over which to count padding cells for
-      application of the ratio limit (ie: reset the limit count this
-      often).
-    - Default: 60
-
-XXX: Should we cap padding at these rates, or fully disable it once
-they're crossed? Probably cap?
-
-In order to monitor the quantity of padding to decide if we should alter
-these limits in the consensus, every node will publish the following
-values in a padding-counts line in its extra-info descriptor:
-
- * write-drop-multihop
-   - The number of RELAY_DROP cells sent by this relay to a next hop
-     that is listed in the consensus.
- * write-drop-onehop
-   - The number of RELAY_DROP cells sent by this relay to a next hop
-     that is not listed in the consensus.
- * write-pad
-   - The number of CELL_PADDING cells sent by this relay.
- * write-total
-   - The total number of cells sent by this relay.
- * read-drop-multihop
-   - The number of RELAY_DROP cells read by this relay from a hop
-     that is listed in the consensus.
- * read-drop-onehop
-   - The number of RELAY_DROP cells read by this relay from a hop
-     that is not listed in the consensus.
- * read-pad
-   - The number of CELL_PADDING cells read by this relay.
- * read-total
-   - The total number of cells read by this relay.
-
-Each of these counters will be rounded to the nearest 10,000 cells. This
-rounding parameter will also be listed in the extra-info descriptor line, in
-case we change it in a later release.
-
-In the future, we may decide to introduce Laplace Noise in a similar
-manner to the hidden service statistics, to further obscure padding
-quantities.
-
-4.2. Malicious state machines
-
-The state machine capabilities of RELAY_COMMAND_PADDING_ADAPTIVE are
-very flexible, and as a result may specify conflicting or
-non-deterministic state transitions.
-
-We believe that the rules in Section 3.2.1 for prioritizing transitions
-towards lower states remove any possibility of non-deterministic
-transitions.
-
-However, because of self-triggering property that allows the state
-machines to schedule more padding packets after sending their own
-locally generated padding packets, care must be taken with the
-interaction with the rate limiting rules in Section 4.1. If the limits
-in section 4.1 are exceeded, the state machines should stop, rather than
-continually poll themselves trying to transmit packets and being blocked
-by the rate limiter at another layer.
-
-4.3. Libevent timer exhaustion
-
-As mentioned in section 3.1, scheduled padding may create an excessive
-number of libevent timers. Care should be taken in the implementation to
-devise a way to prevent clients from sending padding requests
-specifically designed to impact the ability of relays to function by
-causing too many timers to be scheduled at once.
-
-XXX: Can we suggest any specifics here? I can imagine a few ways of
-lazily scheduling timers only when they are close to their expiry time,
-and other ways of minimizing the number of pending timer callbacks at a
-given time, but I am not sure which would be best for libevent.
-
-4.4. Side channels
-
-In order to prevent relays from introducing side channels by requesting
-padding from clients, all of these commands should only be valid in the
-outgoing (from the client/OP) direction.
-
-Clients should perform accounting on the amount of padding that they
-receive, and if it exceeds the amount that they have requested, they
-alert the user of a potentially misbehaving node, and/or close the
-circuit.
-
-Similarly, if RELAY_DROP cells arrive from the last hop of a circuit,
-rather than from the expected interior node, clients should alert the
-user of the possibility of that circuit endpoint introducing a
-side-channel attack, and/or close the circuit.
-
-4.5. Memory exhaustion
-
-Because interior nodes do not have information on the current circuits
-SENDME windows, it is possible for malicious clients to consume the
-buffers of relays by specifying padding, and then not reading from the
-associated circuits.
-
-XXX: Tor already had a few flow-control related DoS's in the past[3]. Is
-that defense sufficient here without any mods? It seems like it may be!
-
--------------------
-
-1. https://gitweb.torproject.org/torspec.git/tree/proposals/251-netflow-padding.txt
-2. http://freehaven.net/anonbib/cache/ShWa-Timing06.pdf
-3. https://blog.torproject.org/blog/new-tor-denial-service-attacks-and-defenses



More information about the tor-commits mailing list