[tor-commits] [torspec/master] Re-flow new-crypto-sketch to a 72 columns, add a TODO

nickm at torproject.org nickm at torproject.org
Tue Nov 1 01:22:27 UTC 2011


commit 5d397a19f34212598b98fe1d4fc0ad5945cc0809
Author: Nick Mathewson <nickm at torproject.org>
Date:   Mon Oct 31 11:06:30 2011 -0400

    Re-flow new-crypto-sketch to a 72 columns, add a TODO
---
 proposals/ideas/xxx-new-crypto-sketch.txt |  617 +++++++++++++++--------------
 1 files changed, 326 insertions(+), 291 deletions(-)

diff --git a/proposals/ideas/xxx-new-crypto-sketch.txt b/proposals/ideas/xxx-new-crypto-sketch.txt
index a4893e1..504e658 100644
--- a/proposals/ideas/xxx-new-crypto-sketch.txt
+++ b/proposals/ideas/xxx-new-crypto-sketch.txt
@@ -2,6 +2,18 @@ Title: Design sketch for new crypto ops
 Date: 19 Oct 2011
 Author: Nick Mathewson
 
+TODO:
+   - Write missing sections
+   - Fix XXXXs
+   - Write performance notes
+   - Find rransom's extend proposal
+   - Proofread
+   - Change relay-cipher section:
+     - Pad with zeros.
+     - Encrypt-then-mac.
+     - Revise analysis.
+   - Try to be a little less monlogue-ish, a little more
+
 0. Overview
 
   The point of this document is to discuss what crypto we ought to be using.
@@ -26,96 +38,100 @@ Author: Nick Mathewson
 
 1. Base algorithm choice
 
-  There seem to be two main candidate algorithms for signatures: RSA with big
-  keys (hereinafter "RSA>1024"); and Ed25519, which is DSA with the sharp
-  edges filed off on an Edwards curve related to DJB's Curve25519.  We can
-  look at other ECC groups too.  {But see ECC Notes.}
-
-  For Diffie Hellman: Curve25519 seems like a decent choice; failing that,
-  another .  DH
-  on Z_p with big groups (hereinafter "DH>1024").  {But see ECC notes.}
-
-  For a hash function: SHA256, switching to SHA3 in 2012 when it comes out.
-  It might be worthwhile waiting for SHA3 in most places, and skipping over
-  the sha256 stage entirely.
-
-  For a stream cipher: AES-CTR is in one sense a conservative choice inasmuch
-  as AES is well-analyzed, but AES's well-known issues with cache-based
-  timing attacks are pretty worrisome.  We can mitigate that some by using
-  random secret IVs for AES-CTR, so that we will be encrypting neither
-  attacker-chosen nor attacker-known plaintext with out AES cipher, but
-  that's a bit kludgy.  Salsa20 is what rransom likes these days, but IMO we
-  aren't competent to tell whether it looks good or not; the existing attacks
-  against it don't look like very bad news to me, but who knows whether it's
-  getting enough attention that we can read.  See also ChaCha; see also the
-  other EuroCrypt {XXXX} winners/finalists; see also SHA3 if the SHA3 winner
-  specifies a way to use it as a stream cipher, or specifies an underlying
-  stream/block cipher.
+  There seem to be two main candidate algorithms for signatures: RSA
+  with big keys (hereinafter "RSA>1024"); and Ed25519, which is DSA with
+  the sharp edges filed off on an Edwards curve related to DJB's
+  Curve25519.  We can look at other ECC groups too.  {But see ECC
+  Notes.}
+
+  For Diffie Hellman: Curve25519 seems like a decent choice; failing
+  that, another XXXX.  DH on Z_p with big groups (hereinafter "DH>1024").
+  {But see ECC notes.}
+
+  For a hash function: SHA256, switching to SHA3 in 2012 when it comes
+  out.  It might be worthwhile waiting for SHA3 in most places, and
+  skipping over the sha256 stage entirely.
+
+  For a stream cipher: AES-CTR is in one sense a conservative choice
+  inasmuch as AES is well-analyzed, but AES's well-known issues with
+  cache-based timing attacks are pretty worrisome.  We can mitigate that
+  some by using random secret IVs for AES-CTR, so that we will be
+  encrypting neither attacker-chosen nor attacker-known plaintext with
+  out AES cipher, but that's a bit kludgy.  Salsa20 is what rransom
+  likes these days, but IMO we aren't competent to tell whether it looks
+  good or not; the existing attacks against it don't look like very bad
+  news to me, but who knows whether it's getting enough attention that
+  we can read.  See also ChaCha; see also the other EuroCrypt {XXXX}
+  winners/finalists; see also SHA3 if the SHA3 winner specifies a way to
+  use it as a stream cipher, or specifies an underlying stream/block
+  cipher.
 
   For a random number generator: We currently use OpenSSL seeded with
-  RAND_poll and with platform entropy.  OpenSSL uses RC4 (XXX check).  The
-  platform entropy management can be messy, obscure, or both.  I suggest
-  that:
-    * we should seed our PRNG with more entropy sources if we can find some
-      promising code with an appropriate license
+  RAND_poll and with platform entropy.  OpenSSL uses RC4 (XXX check).
+  The platform entropy management can be messy, obscure, or both.  I
+  suggest that:
+
+    * we should seed our PRNG with more entropy sources if we can find
+      some promising code with an appropriate license
     * instead of just using OpenSSL's PRNG, we should use OpenSSL's PRNG
-      xor'd with some other good PRNG.  (Is Yarrow still cool?  And is there
-      a combine operation better than xor?)
-    * We should re-seed the RNG before and after very sensitive operations,
-      like private key generation.
+      xor'd with some other good PRNG.  (Is Yarrow still cool?  And is
+      there a combine operation better than xor?)
+    * We should re-seed the RNG before and after very sensitive
+      operations, like private key generation.
 
 
 1.1. ECC notes
 
-  ECC is the brave new[*] crypto of the future!  It's faster[**] than doing
-  crypto in Z_n (as we do for RSA and DH now) for equivalent levels of
-  security, and the resulting outputs are much shorter.
-
-  As near as I can tell as a layman, Certicom is muddying the waters as much
-  as possible wrt claiming that it's nigh impractical to deploy ECC without
-  licensing their patents.  This is rather like the silliness that PKP used
-  to pull back in the day, where they claimed that their patents covered not
-  only the existing public key cryptography algorithms, but also the very
-  idea of public key cryptography itself.
-
-  DJB claims that for every patent he's aware of, either that patent doesn't
-  cover his code, or that patent is invalid because of prior art.  I'm not
-  going to try to evaluate these claims, since I'm not supposed to be reading
-  patents for typical "let's avoid the appearance of knowing infringement"
-  reasons.  But before we dive into the world of ECC, we should see if we can
-  ask any friendly patent attorneys and ECC experts for a second or third
-  opinion here.
-
-  I note in passing that nearly all of the patents that DJB mentions in his
-  list would appear to expire over the next 12 months or so.
-
-  Additionally, there are ECC groups out there less fast than DJB's, but more
-  widely available and analyzed.  We should consider some of those too.
-
-  One final issue to investigate is whether using these algorithms will make
-  any major free software distribution decide not to include us.  I seem to
-  recall seeing that one or two of the big ones had at one point decided to
-  ship OpenSSL only with ECC disabled, either because of real patent
-  concerns, or because of an opinion that the certicom license for ECC use in
-  TLS was problematic for free software, or something like that.  We should
-  check that out.
-
-  [*] Actually, it's older than onion routing, and older than some members of
-  the Tor project.
-
-  [**] Actually, because of the common practice of choosing a small-ish prime
-  value (65537) for e in RSA, RSA public key operations can be a little
-  faster than equivalent-security ECDH or ECDSA operations.  The private key
-  operations in RSA are still much much slower.
+  ECC is the brave new[*] crypto of the future!  It's faster[**] than
+  doing crypto in Z_n (as we do for RSA and DH now) for equivalent
+  levels of security, and the resulting outputs are much shorter.
+
+  As near as I can tell as a layman, Certicom is muddying the waters as
+  much as possible wrt claiming that it's nigh impractical to deploy ECC
+  without licensing their patents.  This is rather like the silliness
+  that PKP used to pull back in the day, where they claimed that their
+  patents covered not only the existing public key cryptography
+  algorithms, but also the very idea of public key cryptography itself.
+
+  DJB claims that for every patent he's aware of, either that patent
+  doesn't cover his code, or that patent is invalid because of prior
+  art.  I'm not going to try to evaluate these claims, since I'm not
+  supposed to be reading patents for typical "let's avoid the appearance
+  of knowing infringement" reasons.  But before we dive into the world
+  of ECC, we should see if we can ask any friendly patent attorneys and
+  ECC experts for a second or third opinion here.
+
+  I note in passing that nearly all of the patents that DJB mentions in
+  his list would appear to expire over the next 12 months or so.
+
+  Additionally, there are ECC groups out there less fast than DJB's, but
+  more widely available and analyzed.  We should consider some of those
+  too.
+
+  One final issue to investigate is whether using these algorithms will
+  make any major free software distribution decide not to include us.  I
+  seem to recall seeing that one or two of the big ones had at one point
+  decided to ship OpenSSL only with ECC disabled, either because of real
+  patent concerns, or because of an opinion that the certicom license
+  for ECC use in TLS was problematic for free software, or something
+  like that.  We should check that out.
+
+  [*] Actually, it's older than onion routing, and older than some
+  members of the Tor project.
+
+  [**] Actually, because of the common practice of choosing a small-ish
+  prime value (65537) for e in RSA, RSA public key operations can be a
+  little faster than equivalent-security ECDH or ECDSA operations.  The
+  private key operations in RSA are still much much slower.
 
 2. New identities
 
   Identity keys and their fingerprints are used:
-    - To sign router descriptors
+    - To sign router descriptors.
     - To identify nodes in consensus directories
     - To make sure we're talking to the right node in the link handshake
-    - To make sure that the extending node is talking to the right next node
-      when sending an extend cell
+    - To make sure that the extending node is talking to the right next
+      node when sending an extend cell
     - To identify particular nodes in the hidden service subsystem
     - To identify nodes in the UI in various places
     - Internally, to identify a node uniquely in the codebase.
@@ -124,35 +140,36 @@ Author: Nick Mathewson
 
 2.1. New identities, option 1: RSA>1024, slow migration.
 
-  We use RSA for identity keys indefinitely.  Nearly all operations done with
-  an identity key are signature checking; signing happens only a few times an
-  hour per node even with pathological cases.  Since signature checking is
-  really cheap with RSA, there's no speed advantage for ECC here.  (There is
-  a space advantage, since the keys are much smaller.)
-
-  The easiest way to migrate to longer identity keys is to tell all Tors to
-  begin accepting longer identity keys now, and to tweak all our protocols so
-  that longer RSA identity keys are understood.  We should then have a pair
-  of parameters in the consensus that determines the largest and smallest
-  acceptable identity key size in the network.  Clients and servers should
-  reject any keys longer or shorter than specified.  Once all versions of Tor
-  can accept long identity keys, we raise the maximum size from 1024 to
-  somewhere in the 2048-4096 range.
+  We use RSA for identity keys indefinitely.  Nearly all operations done
+  with an identity key are signature checking; signing happens only a
+  few times an hour per node even with pathological cases.  Since
+  signature checking is really cheap with RSA, there's no speed
+  advantage for ECC here.  (There is a space advantage, since the keys
+  are much smaller.)
+
+  The easiest way to migrate to longer identity keys is to tell all Tors
+  to begin accepting longer identity keys now, and to tweak all our
+  protocols so that longer RSA identity keys are understood.  We should
+  then have a pair of parameters in the consensus that determines the
+  largest and smallest acceptable identity key size in the network.
+  Clients and servers should reject any keys longer or shorter than
+  specified.  Once all versions of Tor can accept long identity keys, we
+  raise the maximum size from 1024 to somewhere in the 2048-4096 range.
 
 2.2. New identities option 2: RSA>1024, faster migration.
 
-  We use RSA for identity keys indefinitely as above.  But we allow nodes to
-  begin having longer identities now, even though older Tors won't understand
-  them.  This implies, of course, that every such node needs to have at least
-  2 identities: one RSA1024 identity for backward compatibility, one RSA>1024
-  identity for more secure identification.
+  We use RSA for identity keys indefinitely as above.  But we allow
+  nodes to begin having longer identities now, even though older Tors
+  won't understand them.  This implies, of course, that every such node
+  needs to have at least 2 identities: one RSA1024 identity for backward
+  compatibility, one RSA>1024 identity for more secure identification.
 
-  We would have these identities cross-certify as follows: All keys would be
-  listed in the router descriptor.  RSA>1024 keys would be called something
-  other than identity-key, so as not to confuse older clients.  A signature
-  with the RSA>1024 key would appear right before the current RSA1024
-  signature.  This way, signed material would include both keys, and would be
-  signed by both keys.
+  We would have these identities cross-certify as follows: All keys
+  would be listed in the router descriptor.  RSA>1024 keys would be
+  called something other than identity-key, so as not to confuse older
+  clients.  A signature with the RSA>1024 key would appear right before
+  the current RSA1024 signature.  This way, signed material would
+  include both keys, and would be signed by both keys.
 
      [In other words, descriptors would look something like:
 
@@ -169,11 +186,13 @@ Author: Nick Mathewson
       ...
       ext-signature
       -----BEGIN SIGNATURE-----
-      signature of everything through "ext-signature\n", using the long key
+      signature of everything through "ext-signature\n",
+      using the long key
       -----END SIGNATURE-----
       router-signature
       -----BEGIN SIGNATURE-----
-      signature of everything through "router-signature\n", using the short key
+      signature of everything through "router-signature\n",
+      using the short key
       -----END SIGNATURE-----
 
      ]
@@ -181,15 +200,15 @@ Author: Nick Mathewson
   See "UI notes" in the "new fingerprints" section below for some of the
   implications of letting nodes have multiple identity keys.
 
-  We'll need to advertise these new identities in consensus directories too;
-  see XXXX below for more info there.
+  We'll need to advertise these new identities in consensus directories
+  too; see XXXX below for more info there.
 
 2.3. New identities option 3: RSA>1024 and/or Ed25519, faster migration
 
-  As in option 2 above, but new keys can also be Ed25519.  If we expect that
-  not all installations will allow Ed25519 (see "ECC Notes", section 1.1),
-  we'll need to say that every server with an Ed25519 key must also have an
-  RSA>1024 key.
+  As in option 2 above, but new keys can also be Ed25519.  If we expect
+  that not all installations will allow Ed25519 (see "ECC Notes",
+  section 1.1), we'll need to say that every server with an Ed25519 key
+  must also have an RSA>1024 key.
 
 2.4. Implications for current use of identity keys
 
@@ -204,27 +223,29 @@ Author: Nick Mathewson
 
   The current v3 link handshake can handle presenting multiple identity
   certificates in the CERT cell.  We should consider ourselves to be
-  connected to a node with identity X if _any_ of the identity certificates
-  that it presents in its authenticated CERT cell has identity X.  To handle
-  EXTEND cells correctly, we should verify every identity we can.
+  connected to a node with identity X if _any_ of the identity
+  certificates that it presents in its authenticated CERT cell has
+  identity X.  To handle EXTEND cells correctly, we should verify every
+  identity we can.
 
     - To make sure that the extending node is talking to the right next node
       when sending an extend cell
 
-  The new extend cell format needs to allow the client to tell the extending
-  node about some identity for the destination node that the extending node
-  will be able to understand.  This is a capability of the extending node
-  that the client needs to be able to check. (Also, the extend cell needs to
-  hash that identity in a form the extending node can understand; but that's
-  a fingerprint issue.)
+  The new extend cell format needs to allow the client to tell the
+  extending node about some identity for the destination node that the
+  extending node will be able to understand.  This is a capability of
+  the extending node that the client needs to be able to check. (Also,
+  the extend cell needs to hash that identity in a form the extending
+  node can understand; but that's a fingerprint issue.)
 
     - To determine which part of the circuit ID space to use on a Tor
       instance's links.
 
-  We can continue to use RSA1024 identity key comparison here by default.  We
-  can also use some other parameter of the v3 handshake, or introduce a new
-  link protocol where if the initiator authenticates, the initiator always
-  gets the low circIDs and the responder always gets the high ones.
+  We can continue to use RSA1024 identity key comparison here by
+  default.  We can also use some other parameter of the v3 handshake, or
+  introduce a new link protocol where if the initiator authenticates,
+  the initiator always gets the low circIDs and the responder always
+  gets the high ones.
 
     - To identity nodes in consensus directories
     - To identify nodes in the UI in various places
@@ -239,20 +260,20 @@ Author: Nick Mathewson
 2.5. Migrating away from short ID keys entirely
 
   Eventually no version of Tor that requires 1024-bit identity keys will
-  remain.  When that happens, we should stop using them entirely.  That means
-  that if we take any path other than the "slow migration" path of 2.1, we'll
-  need to make everything that looks at a node's identity also accept nodes
-  with _only_ a RSA>1024/Ed25519 identity.
+  remain.  When that happens, we should stop using them entirely.  That
+  means that if we take any path other than the "slow migration" path of
+  2.1, we'll need to make everything that looks at a node's identity
+  also accept nodes with _only_ a RSA>1024/Ed25519 identity.
 
-  At the directory service level, we should have an option to allow nodes
-  without RSA1024 identity keys (off until all clients and nodes accept new
-  identity keys).
+  At the directory service level, we should have an option to allow
+  nodes without RSA1024 identity keys (off until all clients and nodes
+  accept new identity keys).
 
 2.6. Implications for directory information
 
-  Clients must know a hash for each node's identity key, or else they can't
-  make an authenticated connection to the node or tell ORs how to extend to
-  the node.
+  Clients must know a hash for each node's identity key, or else they
+  can't make an authenticated connection to the node or tell ORs how to
+  extend to the node.
 
 
 3. New fingerprints
@@ -261,43 +282,46 @@ Author: Nick Mathewson
   encoding of the RSA1024 identity key.  We encode this in hex almost
   everywhere, and prefix it with a $.
 
-  I propose that fingerprints of the future be determined by taking a digest
-  using SHA256 or SHA3 of:
+  I propose that fingerprints of the future be determined by taking a
+  digest using SHA256 or SHA3 of:
 
       "Hash Algorithm Name", "Key Type Name", encoded key
 
-  When representing these internally, we should include the hash algorithm
-  that was used.  When representing them in the UI, we should use the
-  notation %b64, where b64 is a base-64 encoding, omitting the trailing =s.
+  When representing these internally, we should include the hash
+  algorithm that was used.  When representing them in the UI, we should
+  use the notation %b64, where b64 is a base-64 encoding, omitting the
+  trailing =s.
 
-  (Other plausible characters to use are @, ?, +, ~, =, etc.  I like %, but
-  can be persuaded.  Bikeshed bikeshed bikeshed.)
+  (Other plausible characters to use are @, ?, +, ~, =, etc.  I like %,
+  but can be persuaded.  Bikeshed bikeshed bikeshed.)
 
-  Since 43 base-64 characters is enough to represent a 256-bit digest, with 2
-  bits left over, I propose that the b64 value encode
+  Since 43 base-64 characters is enough to represent a 256-bit digest,
+  with 2 bits left over, I propose that the b64 value encode
       hh | D(hash algorithm name, key type, encoded key),
+
   where hh is a 2-bit value, with one of the values:
       00 -- sha256
       01 -- sha3
       10 -- to be determined
       11 -- reserved.
 
-  We should investigate in the interface whether it's plausible to allow a
-  prefix of a node ID where the full ID would otherwise be required.  That
-  seems risky for short prefixes, though.
+  We should investigate in the interface whether it's plausible to allow
+  a prefix of a node ID where the full ID would otherwise be required.
+  That seems risky for short prefixes, though.
 
 3.1. How many fingerprints is that anyway?!
 
-  Suppose that we allow sha256 and sha3 as hash algorithms, and we allow each
-  node to have 3 identity keys: one RSA1024, one RSA>1024, and one ECC.  Then
-  we would have 7 fingerprints (6 plus the legacy SHA1(RSA1024) fingerprint),
-  for a total of 20+6*32==212 bytes per node.
+  Suppose that we allow sha256 and sha3 as hash algorithms, and we allow
+  each node to have 3 identity keys: one RSA1024, one RSA>1024, and one
+  ECC.  Then we would have 7 fingerprints (6 plus the legacy
+  SHA1(RSA1024) fingerprint), for a total of 20+6*32==212 bytes per
+  node.
 
-  It's not a horrible problem to accept them all in the UI, but the UI isn't
-  the only place that needs to know fingerprints.  Instead, let's say that
-  RSA1024 identities are only identified with SHA1 hashes.  This limits our
-  fingerprint load to a more manageable 20+32*2 == 84 bytes per node.  Still
-  not great, though.
+  It's not a horrible problem to accept them all in the UI, but the UI
+  isn't the only place that needs to know fingerprints.  Instead, let's
+  say that RSA1024 identities are only identified with SHA1 hashes.
+  This limits our fingerprint load to a more manageable 20+32*2 == 84
+  bytes per node.  Still not great, though.
 
 3.2. What does this imply for the UI?
 
@@ -317,20 +341,21 @@ Author: Nick Mathewson
 4.2. More fingerprints
 
   Because extending from node A to node B requires that we have node B's
-  fingerprint in a way that node A will understand, it is not enough to get a
-  set of identity fingerprints for each node in the format _we_ like best.
-  Instead, we must .
+  fingerprint in a way that node A will understand, it is not enough to
+  get a set of identity fingerprints for each node in the format _we_
+  like best.  Instead, we must .
 
 
 4.x. An option: compound signatures on directory objects
 
-   In Tor 0.2.2.x and later, when we check a signature on a directory object
-   (not including hidden service descriptors), we only look at the first
-   DIGEST_LEN bytes of the RSA-signed data.  Once 0.2.1.x is obsolete, or on
-   any types of signatures not checked in 0.2.1.x, we can use the rest of the
-   space.  (We're using PKCS1 padding on our signatures, which has an
-   overhead of 11 bytes.  Signing a SHA1 hash with a 1024-bit key therefore
-   leaves 128-11-20==97 more bytes we could use for a SHA2 or a SHA3 hash.)
+   In Tor 0.2.2.x and later, when we check a signature on a directory
+   object (not including hidden service descriptors), we only look at
+   the first DIGEST_LEN bytes of the RSA-signed data.  Once 0.2.1.x is
+   obsolete, or on any types of signatures not checked in 0.2.1.x, we
+   can use the rest of the space.  (We're using PKCS1 padding on our
+   signatures, which has an overhead of 11 bytes.  Signing a SHA1 hash
+   with a 1024-bit key therefore leaves 128-11-20==97 more bytes we
+   could use for a SHA2 or a SHA3 hash.)
 
 4.x.
 
@@ -342,121 +367,127 @@ Author: Nick Mathewson
 
 6. Relay crypto changes
 
-There are a few things we might want out of improved relay crypto.  They
-include:
+  There are a few things we might want out of improved relay crypto.
+  They include:
    - Resistance to end-to-end bitwise tagging attacks.
    - Better resistance to malleability.
-   - If using counter mode, no block-cipher operations on any value known
-     to the attacker.
+   - If using counter mode, no block-cipher operations on any value
+     known to the attacker.
 
-I'll try to provide these in increasing order of difficulty.  None of these
-is necessarily correct; I should look for a security proof or a better
-construction for any that we seem likely to use.
+  I'll try to provide these in increasing order of difficulty.  None of
+  these is necessarily correct; I should look for a security proof or a
+  better construction for any that we seem likely to use.
 
-Rationales: Our existing malleability resistance is a kludge.  Doing no
-block-cipher ops on attacker-known values increases our security margins a
-little.  Our arguments about tagging attacks hold that an attacker who
-controls both ends has plenty of ways to win even if tagging attacks are
-foiled; nonetheless, most of these ways are technically slightly more
-difficult than xor-based tagging, and it could be useful to boost our
-defense-in-depth a little bit, just in case other active end-to-end attacks
-turn out to be harder than we'd though.)
+  Rationales: Our existing malleability resistance is a kludge.  Doing
+  no block-cipher ops on attacker-known values increases our security
+  margins a little.  Our arguments about tagging attacks hold that an
+  attacker who controls both ends has plenty of ways to win even if
+  tagging attacks are foiled; nonetheless, most of these ways are
+  technically slightly more difficult than xor-based tagging, and it
+  could be useful to boost our defense-in-depth a little bit, just in
+  case other active end-to-end attacks turn out to be harder than we'd
+  though.)
 
-Option 1: Use AES-CTR in a less scary mode
+6.1. Option 1: Use AES-CTR in a less scary mode
 
-   When doing key expansion, in addition to establishing Kf, Kb, Df, and Db,
-   also establish IVf and IVb.  Use the current relay crypto, except instead
-   of starting the counters at 0, start them at IVf and IVb.  This way, an
-   attacker doesn't have any known plaintexts to work with, which makes AES a
-   little more robust.
+  When doing key expansion, in addition to establishing Kf, Kb, Df, and
+   Db, also establish IVf and IVb.  Use the current relay crypto, except
+   instead of starting the counters at 0, start them at IVf and IVb.
+   This way, an attacker doesn't have any known plaintexts to work with,
+   which makes AES a little more robust.
 
-Option 2: As 1, but tagging attacks garble the circuit after one block.
+6.2. Option 2: As 1, but tagging attacks garble the circuit after one block.
 
    Keep an HMAC of all previously received encrypted cells on a circuit.
-   When decrypting a cell, use this HMAC value to determine the first 64 bits
-   of the counter; increment the low 64 bits of the counter as usual.
+   When decrypting a cell, use this HMAC value to determine the first 64
+   bits of the counter; increment the low 64 bits of the counter as
+   usual.
 
-   This way, if an adversary flips any bits before passing the stream through
-   an honest node, no _subsequent_ block will be recoverable.
+   This way, if an adversary flips any bits before passing the stream
+   through an honest node, no _subsequent_ block will be recoverable.
 
-   To prevent any part of the stream from being re-used, close any circuit if
-   the low 64 bits of the counter would ever wrap (that is, around 295
-   million terabytes).
+   To prevent any part of the stream from being re-used, close any
+   circuit if the low 64 bits of the counter would ever wrap (that is,
+   around 295 million terabytes).
 
-   (If we're using a stream cipher with fast re-key, then we can just have
-   the key used for each block be an HMAC of all previously received
-   ciphertext.)
+   (If we're using a stream cipher with fast re-key, then we can just
+   have the key used for each block be an HMAC of all previously
+   received ciphertext.)
 
 Option 3: As 1, but tagging attacks garble the circuit in the same block.
 
    Use a large-block cipher mode, such as BEAR or LIONESS (depending on
-   whether we need a PRP or SPRP).  Base the key material for each block on
-   an HMAC of all previous blocks' ciphertexts.
+   whether we need a PRP or SPRP).  Base the key material for each block
+   on an HMAC of all previous blocks' ciphertexts.
 
-   This way, if an adversary makes any alteration in a block, that block and
-   all subsequent blocks will be garbled.  It's more expensive than 2,
-   though, especially if we need to use a LIONESS construction.
+   This way, if an adversary makes any alteration in a block, that block
+   and all subsequent blocks will be garbled.  It's more expensive than
+   2, though, especially if we need to use a LIONESS construction.
 
-   {I considered IGE here, with a trick where odd-numbered nodes on a circuit
-   start from the front of the block and even-numbered nodes start from the
-   end, but it didn't seem much better.  We should investigate relative
-   performance, though.}
+   {I considered IGE here, with a trick where odd-numbered nodes on a
+   circuit start from the front of the block and even-numbered nodes
+   start from the end, but it didn't seem much better.  We should
+   investigate relative performance, though.}
 
 Option 4: Shall we have middle nodes be able to fast-stop bad data?
 
-   In all the above options, if a cell is altered, the middle node can at
-   best turn that cell and the rest of the cells on the circuit into garbage,
-   which the last node won't deliver (if honest) or can't deliver (if dishonest).
-
-   Might we prefer to do as in mixnets, and have nodes kill circuits upon
-   receiving altered cells?
-
-   I'm not so sure.  It's relatively expensive in per-cell overhead, and the
-   next-best attack to the one it prevents isn't so great.
-
-   Consider that if option 3 is in place, an end-to-end attacker who wants to
-   do a tagging attack at one node can garble the rest of the circuit, and
-   see if the output is garbled at the exit node.  But such an attacker could
-   just as easily close the circuit at one of those nodes and watch for a
-   corresponding close event, or even better -- simply pause traffic on that
-   circuit for a while and watch for a corresponding gap at the exit.  The
-   only advantage of the garbling attack would be that garbled cells are
-   presumably rarer than circuit closes or traffic pauses, and thus easier to
-   use to distinguish target circuits.  But that's still bunk; the other
-   attacks win fine, and the pause attack doesn't risk detection so much.
-
-   Still, to do this one, we'd want to have outgoing and incoming circuits
-   treated differently.  Incoming cells could work as in 1 or 2 or 3 above;
-   outgoing cells would want to have a header portion as in mixmaster, where
-   each node checks that the first N bits of the header match a MAC of all
-   data seen so far, *including the rest of the cell*.  They'd then decrypt
-   the rest of the cell, remove the first N bits of the header, and re-pad
-   the header with N bits at the end, taken from a PRNG whose seed is shared
-   with the client.  (This is basically how mixmaster works, and how
-   mixminion works in the common case.)
-
-   The space overhead here is kind of large: N bits per cell per node.  In
-   the most paranoid case, if we used 256-byte HMACs on 3-node paths, that's
-   96 bytes per cell, which is more than 20% of the total length.  But we can
-   probably do better if we let the CREATE operation also tell the node some
-   N to check.  For example, the first node doesn't need to check any bits.
-   The second and third nodes could check 64 bits apiece; that only has 16
-   bytes overhead, and high probability of catching any changes. (Birthday
-   attacks don't matter here, and an attacker who mounts this attack for long
-   enough to accidentally find a 64-bit mac will break so many circuits in
-   the process as to become totally unreliable.
-
-   But all of this leaks the path lengths and position on the path to various
-   nodes.  We might open ourselves up to partitioning attacks if different
-   clients choose different numbers of bits.  What's more, we might leak the
-   length of the path to the last node by how much junk there is at the end
-   of the cell.
+   In all the above options, if a cell is altered, the middle node can
+   at best turn that cell and the rest of the cells on the circuit into
+   garbage, which the last node won't deliver (if honest) or can't
+   deliver (if dishonest).
+
+   Might we prefer to do as in mixnets, and have nodes kill circuits
+   upon receiving altered cells?
+
+   I'm not so sure.  It's relatively expensive in per-cell overhead, and
+   the next-best attack to the one it prevents isn't so great.
+
+   Consider that if option 3 is in place, an end-to-end attacker who
+   wants to do a tagging attack at one node can garble the rest of the
+   circuit, and see if the output is garbled at the exit node.  But such
+   an attacker could just as easily close the circuit at one of those
+   nodes and watch for a corresponding close event, or even better --
+   simply pause traffic on that circuit for a while and watch for a
+   corresponding gap at the exit.  The only advantage of the garbling
+   attack would be that garbled cells are presumably rarer than circuit
+   closes or traffic pauses, and thus easier to use to distinguish
+   target circuits.  But that's still bunk; the other attacks win fine,
+   and the pause attack doesn't risk detection so much.
+
+   Still, to do this one, we'd want to have outgoing and incoming
+   circuits treated differently.  Incoming cells could work as in 1 or 2
+   or 3 above; outgoing cells would want to have a header portion as in
+   mixmaster, where each node checks that the first N bits of the header
+   match a MAC of all data seen so far, *including the rest of the
+   cell*.  They'd then decrypt the rest of the cell, remove the first N
+   bits of the header, and re-pad the header with N bits at the end,
+   taken from a PRNG whose seed is shared with the client.  (This is
+   basically how mixmaster works, and how mixminion works in the common
+   case.)
+
+   The space overhead here is kind of large: N bits per cell per node.
+   In the most paranoid case, if we used 256-byte HMACs on 3-node paths,
+   that's 96 bytes per cell, which is more than 20% of the total length.
+   But we can probably do better if we let the CREATE operation also
+   tell the node some N to check.  For example, the first node doesn't
+   need to check any bits.  The second and third nodes could check 64
+   bits apiece; that only has 16 bytes overhead, and high probability of
+   catching any changes. (Birthday attacks don't matter here, and an
+   attacker who mounts this attack for long enough to accidentally find
+   a 64-bit mac will break so many circuits in the process as to become
+   totally unreliable.
+
+   But all of this leaks the path lengths and position on the path to
+   various nodes.  We might open ourselves up to partitioning attacks if
+   different clients choose different numbers of bits.  What's more, we
+   might leak the length of the path to the last node by how much junk
+   there is at the end of the cell.
 
    Here's a simple construction for this format, to be concrete:
 
      The CREATE operation's KDF produces the following outputs:
-           Kf, IVf  (stream cipher key, and possibly IV, for forward direction)
-           Kb, IVb  (stream cipher key, and possibly IV, for reverse direction)
+           Kf, IVf  (stream cipher key and IV for forward direction)
+           Kb, IVb  (stream cipher key and IV for reverse direction)
            Mf       (MAC key for forward direction)
            Mb       (MAC key for reverse direction)
            SEEDf    (PRNG key for forward direction)
@@ -465,27 +496,28 @@ Option 4: Shall we have middle nodes be able to fast-stop bad data?
            MACBYTESb (an integer between 0 and 32 inclusive)
            CANEXIT   (boolean: can we exit from this hop?)
 
-     Let Kf[i], Mf[i], etc denote the parameter Kf, Mf, etc as shared between
-     the client and the i'th node in its circuit.
-
-     Relay cells sent towards the client have the following plaintext format:
+     Let Kf[i], Mf[i], etc denote the parameter Kf, Mf, etc as shared
+     between the client and the i'th node in its circuit.
 
+     Relay cells sent towards the client have the following plaintext
+     format:
          Body:
            Content:
              Relay Command [1 byte]
              StreamID      [2 bytes]
              Length        [2 bytes]
              Data          [Up to CELL_DATA_LEN-5-MACBYTESb bytes]
-             Padding       [randomly generated as needed to fill the cell]
+             Padding       [randomly generated as needed to fill the
+                            cell]
            MAC(All previous encrypted content + encrypted content,
                                   Mb)[:MACBYTESb]   [MACBYTESb bytes]
 
-     The originator of the client-bound cell encrypts the content with the
-     next part of its Kb,IVb stream, then appends the MAC.
+     The originator of the client-bound cell encrypts the content with
+     the next part of its Kb,IVb stream, then appends the MAC.
 
-     Non-clients receiving a client-bound relay cell encrypt the entire cell
-     body, MAC included, with the next part of the stream cipher that was
-     keyed with Kb,IVb.
+     Non-clients receiving a client-bound relay cell encrypt the entire
+     cell body, MAC included, with the next part of the stream cipher
+     that was keyed with Kb,IVb.
 
      When the client receives a relay cell body, it iteratively does:
 
@@ -497,15 +529,15 @@ Option 4: Shall we have middle nodes be able to fast-stop bad data?
             passed by every node on the circuit.}
 
            If MACBYTESb[i]>0, check whether MAC(cells_i | cellbody,
-           Mb[i])[:MACBYTESb[i]] the last MACBYTESb[i] bytes of the cell.  If
-           so, this cell is from node i.
+           Mb[i])[:MACBYTESb[i]] the last MACBYTESb[i] bytes of the
+           cell.  If so, this cell is from node i.
 
            If this cell is from node i, decrypt the first
            CELL_DATA_LEN-MACBYTESb[i] bytes of the cell using the stream
            keyed with Kb[i],IVb[i].  Act on it as a relay cell.
 
-           Otherwise decrypt the entire cell, MAC included, with the stream
-           keyed with Kb[i], IVb[i].
+           Otherwise decrypt the entire cell, MAC included, with the
+           stream keyed with Kb[i], IVb[i].
 
       If no node sent this cell: it's junk and somebody is probably
       messing with us!  Destroy the circuit.
@@ -535,7 +567,8 @@ Option 4: Shall we have middle nodes be able to fast-stop bad data?
 
          For i in 2...N:
              Let L = len(PADSEEN[i-1])
-             Let PADSEEN[i] = (PADSEEN[i-1] xor STREAM[i-1][CELL_DATA_LEN-L:]) | PAD[i-1]
+             Let PADSEEN[i] = (PADSEEN[i-1] xor
+                              STREAM[i-1][CELL_DATA_LEN-L:]) | PAD[i-1]
 
          For i in N down to 1:
 
@@ -549,15 +582,15 @@ Option 4: Shall we have middle nodes be able to fast-stop bad data?
 
      To receive an outbound cell:
 
-         Let M be the first MACBYTESf bytes of the cell, let REST be the rest
-         of the cell, and let "cells" be all previous cells on this circuit.
-         If CANEXIT, and M = MAC(cells|rest|"RECOGNIZED", Mb)[:MACBYTESf],
-         and MACBYTESf > 0, this cell is for us.  If M = MAC(cells|rest|"OK",
-         Mb)[:MACBYTESf], this cell is not for us, but is valid.  Otherwise,
-         destroy the circuit.
+         Let M be the first MACBYTESf bytes of the cell, let REST be the
+         rest of the cell, and let "cells" be all previous cells on this
+         circuit.  If CANEXIT, and M = MAC(cells|rest|"RECOGNIZED",
+         Mb)[:MACBYTESf], and MACBYTESf > 0, this cell is for us.  If M
+         = MAC(cells|rest|"OK", Mb)[:MACBYTESf], this cell is not for
+         us, but is valid.  Otherwise, destroy the circuit.
 
-         Decrypt REST using the stream cipher keyed with Kf,IVf.  If this
-         cell is for us, act on it as a relay cell.  Otherwise, let
+         Decrypt REST using the stream cipher keyed with Kf,IVf.  If
+         this cell is for us, act on it as a relay cell.  Otherwise, let
          PAD = the next MACBYTESf[i] bytes of the PRNG keyed with SEEDf,
          and relay REST | PAD.
 
@@ -572,28 +605,30 @@ Option 4: Shall we have middle nodes be able to fast-stop bad data?
      PICKING MACBYTESf,MACBYTESb.
 
          We don't need to worry about birthday attacks:
-            Because we're using a MAC, only the parties who are making the
-            MACs could try to do a brute-force search for a collision, but
-            they have no reason to do so.
 
-            If a collision occurs accidentally, an adversary can't substitute
-            an earlier-seen cell for a later one with the same MAC, since the
-            MAC covers not only the cell, but all previous cells on the
-            circuit.
-         So 16 bytes is about the most we should ever do, given our usual
-         security parameters.  Let me moot the number 8 for MACBYTESb.
+            Because we're using a MAC, only the parties who are making
+            the MACs could try to do a brute-force search for a
+            collision, but they have no reason to do so.
+
+            If a collision occurs accidentally, an adversary can't
+            substitute an earlier-seen cell for a later one with the
+            same MAC, since the MAC covers not only the cell, but all
+            previous cells on the circuit.
+
+         So 16 bytes is about the most we should ever do, given our
+         usual security parameters.  Let me moot the number 8 for
+         MACBYTESb.
 
          For outbound cells, for any hop we can exit from, choosing
-         MACBYTESf=6 gets us the current security level.  For the first hop,
-         assuming we don't exit from it, choosing MACBYTESf=0 is totally
-         safe, since the link crypto guarantees that nothing was corrupted on
-         the way.
+         MACBYTESf=6 gets us the current security level.  For the first
+         hop, assuming we don't exit from it, choosing MACBYTESf=0 is
+         totally safe, since the link crypto guarantees that nothing was
+         corrupted on the way.
 
          In general, to prevent an end-to-end tagging attack, it seems
          sufficient to do something like setting MACBYTES=8 for the last
          hop, and MACBYTES=8 for one hop in the middle.
 
-
 ACKS
 
    Lots of the good ideas and concerns here are due to Robert Ransom.





More information about the tor-commits mailing list