What about this for modification resistance?<br><div>We keep a count of all cells passing and use AES in CTR mode with a 2 part counter: the first part the cell counter, the second one a block counter. Then to authenticate the cell we can use a 16 byte tag and a Wegman-Carter MAC. This gives a total overhead of 48 bytes for a three hop link, which is half the cited one, and which</div>
<div>is provably as secure as AES.</div><div><br></div><div>ChaCha is a component part of one of the SHA-3 finalists, namely JH. If JH is selected as the SHA3 candidate, this may (read may) entail something about the security of ChaCha. The HAIFA construction JH uses doesn&#39;t say much about proofs of security, unlike the sponge papers.</div>
<div><br></div><div>ECC groups don&#39;t matter much: there are some really bad choices out there, but any attack against Curve25519 is</div><div>going to probably imply an attack against NIST P-256 as well. Its not that different from picking a particular DH prime: some are bad because p-1 is smooth, but if not then they all look the same.</div>
<div><br></div><div>2012 is coming soon: The schedule says between March and June of this year SHA3 will be announced. Everything after that involves bureaucracy. Why switch to SHA256 and then to SHA3 when we won&#39;t be done before March anyway?</div>
<div><br></div><div>In general options are bad in crypto: we should migrate as few times as possible to avoid various attacks that might involve degrading a negotiation. As for Certicom their patents were licensed by NIST. Unfortunately for them they openly admit on their website that these are mostly implementation patents. To my untrained eye DJB&#39;s analysis is spot on. There is also <a href="http://tools.ietf.org/html/rfc6090">http://tools.ietf.org/html/rfc6090</a> which seems to do something similar.</div>
<div><br></div><div>Sincerely,<br>Watson Ladd</div><div><div class="gmail_quote">On Mon, Oct 31, 2011 at 8:25 PM, Nick Mathewson <span dir="ltr">&lt;<a href="mailto:nickm@torproject.org">nickm@torproject.org</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Here&#39;s an early draft document trying to sketch out the parameters for<br>
migrating to better crypto ops and designs in the future.<br>
<br>
Comments are invited, even comments of the form &quot;you will need to be<br>
much more specific here before I can say anything sensible.&quot;<br>
<br>
This is proposals/ideas/xxx-new-crypto-sketch.txt in the torspec repository.<br>
<br>
<br>
<br>
Title: Design sketch for new crypto ops<br>
Date: 31 Oct 2011<br>
Author: Nick Mathewson<br>
<br>
0. Overview<br>
<br>
  The point of this document is to discuss what crypto we ought to be using.<br>
  See &quot;Initial Thoughts on Migrating Tor to New Cryptography&quot; from last year<br>
  for general guidelines and principles.<br>
<br>
  In broad strokes, the parts of our crypto are:<br>
<br>
    IDENTITY KEYS AND FINGERPRINTS<br>
       Addressed here in Section 2.<br>
    LINK CRYPTO (TLS) --<br>
       Addressed in proposals 176, 184.  We say a little here in section 5,<br>
       though.<br>
    CREATE/EXTEND CRYPTO --<br>
       Addressed in xxx-ntor-handshake.txt and rransom&#39;s EXTEND draft at<br>
       [*] and subsequent discussion on the tor-dev mailing list.  Not<br>
       considered here.<br>
    RELAY CRYPTO<br>
       Addressed here in Section 6.<br>
    DIRECTORY SYSTEM<br>
       Addressed here.<br>
    HIDDEN SERVICE SYSTEM<br>
       Addressed in a forthcoming document by rransom.<br>
<br>
[*] <a href="https://lists.torproject.org/pipermail/tor-dev/2011-March/002547.html" target="_blank">https://lists.torproject.org/pipermail/tor-dev/2011-March/002547.html</a><br>
<br>
1. Base algorithm choice<br>
<br>
  There seem to be two main candidate algorithms for signatures: RSA<br>
  with big keys (hereinafter &quot;RSA&gt;1024&quot;); and Ed25519, which is DSA with<br>
  the sharp edges filed off on an Edwards curve related to DJB&#39;s<br>
  Curve25519.  We can look at other ECC groups too.  {But see ECC<br>
  Notes in 1.1 below.}<br>
<br>
  FOR DIFFIE-HELLMAN: Curve25519 seems like a decent choice; failing<br>
  that, one of the NIST P-groups.  Failing that, DH on Z_p with big<br>
  groups (hereinafter &quot;DH&gt;1024&quot;).  {But see ECC Notes in 1.1 below.}<br>
<br>
  FOR A HASH FUNCTION: SHA256, switching to SHA3 in 2012 when it comes<br>
  out.  It might be worthwhile waiting for SHA3 in most places and<br>
  skipping over the SHA256 stage entirely.<br>
<br>
  FOR A STREAM CIPHER: AES-CTR is in one sense a conservative choice<br>
  inasmuch as AES is well-analyzed, but AES&#39;s well-known issues with<br>
  cache-based timing attacks are pretty worrisome.  We can mitigate that<br>
  some by using random secret IVs for AES-CTR, so that we will be<br>
  encrypting neither attacker-chosen nor attacker-known plaintext with<br>
  our AES cipher, but that&#39;s a bit kludgy.  There are also supposed to<br>
  be time-invariant implementations that use Intel&#39;s AESNI instructions<br>
  where available, and time-invariant implementations that use<br>
  bit-slicing.<br>
<br>
  Salsa20 is what rransom likes these days, but IMO we aren&#39;t competent<br>
  to tell whether it looks good or not; the existing attacks against it<br>
  don&#39;t look like very bad news to me, but who knows whether it&#39;s<br>
  getting enough attention that we can read.  See also ChaCha; see also<br>
  the other eSTREAM winners/finalists; see also SHA3 if the SHA3 winner<br>
  specifies a way to use it as a stream cipher, or specifies an<br>
  underlying stream/block cipher.<br>
<br>
  If we&#39;re feeling cautious, we could run two independently-keyed stream<br>
  ciphers and xor their streams together.<br>
<br>
  FOR A RANDOM NUMBER GENERATOR: We currently use OpenSSL seeded with<br>
  RAND_poll and with platform entropy.  OpenSSL uses a message-digest-<br>
  based algorithm from SSLeay (See <a href="http://linux.die.net/man/3/sslrand" target="_blank">http://linux.die.net/man/3/sslrand</a><br>
  for the ugly details.)  The platform entropy management can be messy,<br>
  obscure, or both.  I suggest that:<br>
<br>
    * We should seed our PRNG with more entropy sources if we can find<br>
      some promising code with an appropriate license<br>
    * Instead of just using OpenSSL&#39;s PRNG, we should use OpenSSL&#39;s<br>
      MD-based PRNG xor&#39;d with some other good PRNG.  (Fortuna,<br>
      maybe. Is there a combine operation better than xor? See also SHA3<br>
      if the SHA3 winner is one that specifies a PRNG mode of<br>
      operation.)<br>
    * We should consider splicing this combined-stream PRNG into OpenSSL<br>
      as the RNG it uses for SSL and key generation.<br>
    * We should re-seed the RNG before and after very sensitive<br>
      operations, like private key generation.<br>
<br>
1.1. ECC notes<br>
<br>
  ECC is the brave new[*] crypto of the future!  It&#39;s faster[**] than<br>
  doing crypto in Z_n (as we do for RSA and DH now) for equivalent<br>
  levels of security, and the resulting outputs are much shorter.<br>
<br>
  As near as I can tell as a layman, Certicom is muddying the waters as<br>
  much as possible wrt claiming that it&#39;s nigh-impractical to deploy ECC<br>
  without licensing their patents.  This is rather like the silliness<br>
  that PKP used to pull back in the day, where they claimed that their<br>
  patents covered not only the existing public key cryptography<br>
  algorithms, but also the very idea of public key cryptography itself.<br>
<br>
  DJB claims that for every patent he&#39;s aware of, either that patent<br>
  doesn&#39;t cover his code, or that patent is invalid because of prior<br>
  art.  I&#39;m not going to try to evaluate these claims, since I&#39;m not<br>
  supposed to be reading patents for typical &quot;let&#39;s avoid the appearance<br>
  of knowing infringement&quot; reasons.  But before we dive into the world<br>
  of ECC, we should see if we can ask any friendly patent attorneys and<br>
  ECC experts for a second or third opinion here.<br>
<br>
  I note in passing that nearly all of the patents that DJB mentions in<br>
  his list would appear to expire over the next 12 months or so.<br>
<br>
  Additionally, there are ECC groups out there less fast than DJB&#39;s, but<br>
  more widely available and analyzed.  We should consider some of those<br>
  too.<br>
<br>
  One final issue to investigate is whether using these algorithms will<br>
  make any major free software distribution decide not to include us.  I<br>
  seem to recall seeing that one or two of the big ones had at one point<br>
  decided to ship OpenSSL only with ECC disabled, either because of real<br>
  patent concerns, or because of an opinion that the Certicom license<br>
  for ECC use in TLS was problematic for free software, or something<br>
  like that.  We should check that out.<br>
<br>
  [*] Actually, it&#39;s older than onion routing, and older than some<br>
  members of the Tor Project.<br>
<br>
  [**] Actually, because of the common practice of choosing a small-ish<br>
  prime value (65537) for e in RSA, RSA public key operations can be a<br>
  little faster than equivalent-security ECDH or ECDSA operations.  The<br>
  private key operations in RSA are still much much slower.<br>
<br>
2. New identities<br>
<br>
  Identity keys and their fingerprints are used:<br>
    - To sign router descriptors.<br>
    - To identify nodes in consensus directories.<br>
    - To make sure we&#39;re talking to the right node in the link handshake.<br>
    - To make sure that the extending node is talking to the right next<br>
      node when sending an extend cell.<br>
    - To identify particular nodes in the hidden service subsystem.<br>
    - To identify nodes in the UI in various places.<br>
    - Internally, to identify a node uniquely in the codebase.<br>
    - To determine which part of the circuit ID space to use on a Tor<br>
      instance&#39;s links.<br>
<br>
2.1. New identities, option 1: &quot;RSA&gt;1024, slow migration&quot;<br>
<br>
  In this option, we use RSA for identity keys indefinitely.  Nearly all<br>
  operations done with an identity key are signature checking; signing<br>
  happens only a few times an hour per node even with pathological<br>
  cases.  Since signature checking is really cheap with RSA, there&#39;s no<br>
  speed advantage for ECC here.  (There is a space advantage, since the<br>
  keys are much smaller.)<br>
<br>
  The easiest way to migrate to longer identity keys is to tell all Tors<br>
  to begin accepting longer identity keys now, and to tweak all our<br>
  protocols so that longer RSA identity keys are understood.  We should<br>
  then have a pair of parameters in the consensus that determines the<br>
  largest and smallest acceptable identity key size in the network.<br>
  Clients and servers should reject any keys longer or shorter than<br>
  specified.  Once all versions of Tor can accept long identity keys, we<br>
  raise the maximum size from 1024 to somewhere in the 2048-4096 range.<br>
<br>
2.2. New identities option 2: &quot;RSA&gt;1024, faster migration&quot;<br>
<br>
  In this option, we use RSA for identity keys indefinitely as above.<br>
  But we allow nodes to begin having longer identities now, even though<br>
  older Tors won&#39;t understand them.  This implies, of course, that every<br>
  such node needs to have at least 2 identities: one RSA1024 identity<br>
  for backward compatibility, one RSA&gt;1024 identity for more secure<br>
  identification.<br>
<br>
  We would have these identities cross-certify as follows: All keys<br>
  would be listed in the router descriptor.  RSA&gt;1024 keys would be<br>
  called something other than identity-key, so as not to confuse older<br>
  clients.  A signature with the RSA&gt;1024 key would appear right before<br>
  the current RSA1024 signature.  This way, signed material would<br>
  include both keys, and would be signed by both keys.<br>
<br>
     [In other words, descriptors would look something like:<br>
<br>
      router foo...<br>
      ...<br>
      identity-key<br>
      -----BEGIN RSA KEY-----<br>
      1024-bit RSA key here<br>
      -----END RSA KEY-----<br>
      ext-identity-key<br>
      -----BEGIN RSA KEY-----<br>
      3072-bit RSA key here<br>
      -----END RSA KEY-----<br>
      ...<br>
      ext-signature<br>
      -----BEGIN SIGNATURE-----<br>
      signature of everything through &quot;ext-signature\n&quot;,<br>
      using the long key<br>
      -----END SIGNATURE-----<br>
      router-signature<br>
      -----BEGIN SIGNATURE-----<br>
      signature of everything through &quot;router-signature\n&quot;,<br>
      using the short key<br>
      -----END SIGNATURE-----<br>
<br>
     ]<br>
<br>
  See &quot;UI notes&quot; in the &quot;new fingerprints&quot; section below for some of the<br>
  implications of letting nodes have multiple identity keys.<br>
<br>
  We&#39;ll need to advertise these new identities in consensus directories<br>
  too; see 4.2 below for more info there.<br>
<br>
2.3. New identities option 3: &quot;RSA&gt;1024 and/or Ed25519, faster migration&quot;<br>
<br>
  As in option 2 above, but new keys can also be Ed25519.  If we expect<br>
  that not all installations will allow Ed25519 (see &quot;ECC Notes&quot;,<br>
  section 1.1), we&#39;ll need to say that every server with an Ed25519 key<br>
  must also have an RSA&gt;1024 key.<br>
<br>
2.4. Implications for current use of identity keys<br>
<br>
  Let&#39;s review our use of identity keys again and make sure that we can<br>
  handle all of them with the ideas above.<br>
<br>
    - To sign router descriptors.<br>
<br>
  We discussed this in 2.2.<br>
<br>
    - To make sure we&#39;re talking to the right node in the link handshake.<br>
<br>
  The current v3 link handshake can handle presenting multiple identity<br>
  certificates in the CERT cell.  We should consider ourselves to be<br>
  connected to a node with identity X if _any_ of the identity<br>
  certificates that it presents in its authenticated CERT cell has<br>
  identity X.  To handle EXTEND cells correctly, we should verify every<br>
  identity we can.<br>
<br>
    - To make sure that the extending node is talking to the right next node<br>
      when sending an extend cell.<br>
<br>
  The new extend cell format needs to allow the client to tell the<br>
  extending node about some identity for the destination node that the<br>
  extending node will be able to understand.  This is a capability of<br>
  the extending node that the client needs to be able to check. (Also,<br>
  the extend cell needs to hash that identity in a form the extending<br>
  node can understand, but that&#39;s a fingerprint issue.)<br>
<br>
    - To determine which part of the circuit ID space to use on a Tor<br>
      instance&#39;s links.<br>
<br>
  We can continue to use RSA1024 identity key comparison here by<br>
  default.  We can also use some other parameter of the v3 handshake, or<br>
  introduce a new link protocol where if the initiator authenticates,<br>
  the initiator always gets the low circIDs and the responder always<br>
  gets the high ones.<br>
<br>
    - To identify nodes in consensus directories.<br>
    - To identify nodes in the UI in various places.<br>
    - Internally, to identify a node uniquely in the codebase.<br>
<br>
  See sections 3 and 4 below.<br>
<br>
    - To identify particular nodes in the hidden service subsystem.<br>
<br>
  Out of scope.<br>
<br>
2.5. Migrating away from short ID keys entirely<br>
<br>
  Eventually, no version of Tor that requires 1024-bit identity keys will<br>
  remain.  When that happens, we should stop using them entirely.  That<br>
  means that if we take any path other than the &quot;slow migration&quot; path of<br>
  2.1, we&#39;ll need to make everything that looks at a node&#39;s identity<br>
  also accept nodes with _only_ a RSA&gt;1024/Ed25519 identity.<br>
<br>
  At the directory service level, we should have an option to allow<br>
  nodes without RSA1024 identity keys (off until all clients and nodes<br>
  accept new identity keys).<br>
<br>
2.6. Selective correctness attacks<br>
<br>
  For any scheme based on having multiple signature types on a router<br>
  descriptor or other document, an attacker could mount a partitioning<br>
  attack by making a document which older clients will accept but newer<br>
  clients will reject.<br>
<br>
  It&#39;s easy to prevent this at the consensus step: directory authorities<br>
  MUST NOT accept any descriptor unless all clients will be able to<br>
  verify it.<br>
<br>
  For bridge descriptors, we need to investigate more carefully.<br>
<br>
3. New fingerprints<br>
<br>
  Right now we compute fingerprints by taking the SHA1 hash of an ASN1<br>
  encoding of the RSA1024 identity key.  We encode this in hex almost<br>
  everywhere, and sometimes prefix it with a $.<br>
<br>
  I propose that fingerprints of the future be determined by taking a<br>
  digest using SHA256 or SHA3 of:<br>
<br>
      &quot;Hash Algorithm Name&quot;, &quot;Key Type Name&quot;, encoded key<br>
<br>
  When representing these internally, we should include the hash<br>
  algorithm that was used.  When representing them in the UI, we should<br>
  use the notation %b64, where b64 is a base-64 encoding, omitting the<br>
  trailing =s.<br>
<br>
  (Other plausible characters to use are @, ?, +, ~, =, etc.  I like %,<br>
  but can be persuaded.  Bikeshed bikeshed bikeshed.)<br>
<br>
  Since 43 base-64 characters is enough to represent a 256-bit digest,<br>
  with 2 bits left over, I propose that the b64 value encode<br>
<br>
      hh | D(hash algorithm name, key type, encoded key)<br>
<br>
  where hh is a 2-bit value, with one of the following values:<br>
<br>
      00 -- sha256<br>
      01 -- sha3<br>
      10 -- to be determined<br>
      11 -- reserved.<br>
<br>
  We should investigate in the interface whether it&#39;s plausible to allow<br>
  a prefix of a node ID where the full ID would otherwise be required.<br>
  That seems risky for short prefixes, though.<br>
<br>
3.1. How many fingerprints is that anyway?!<br>
<br>
  Suppose that we allow sha256 and sha3 as hash algorithms, and we allow<br>
  each node to have 3 identity keys: one RSA1024, one RSA&gt;1024, and one<br>
  ECC.  Then we would have 7 fingerprints (6 plus the legacy<br>
  SHA1(RSA1024) fingerprint), for a total of 20+6*32==212 bytes per<br>
  node.<br>
<br>
  It&#39;s not a horrible problem to accept them all in the UI, but the UI<br>
  isn&#39;t the only place that needs to know fingerprints.  Instead, let&#39;s<br>
  say that RSA1024 identities are only identified with SHA1 hashes.<br>
  This limits our fingerprint load to a more manageable 20+32*2 == 84<br>
  bytes per node.  Still not great, though.<br>
<br>
3.2. What does this imply for the UI?<br>
<br>
  In the UI we&#39;ll lose the property that no node has more than one<br>
  fingerprint: I do not believe that this actually hurts us.<br>
<br>
3.3. Implications for directory information<br>
<br>
  Clients must know a hash for each node&#39;s identity key, or else they<br>
  can&#39;t make an authenticated connection to the node or tell ORs how to<br>
  extend to the node.<br>
<br>
  This means that if client Alice wants to connect to node Bob, Alice<br>
  must have a fingerprint of Bob&#39;s ID key such that she understands the<br>
  ID key type and the fingerprint algorithm.  If Alice wants to extend<br>
  from Bob to Carol, she must have a fingerprint of Carol&#39;s ID key such<br>
  that Bob understands the ID key type and the fingerprint algorithm.<br>
<br>
  So for every node, Alice must not only know a fingerprint that *she*<br>
  can use for that node, but also a set of fingerprints such that every<br>
  node can understand at least one fingerprint in the set.<br>
<br>
  This implies a proliferation of fingerprints!  We should tread<br>
  carefully here.  To prevent proliferation, the easiest solution is not<br>
  to add too many new types and to have a good plan for retiring older<br>
  types.<br>
<br>
3.4. Implications for EXTEND cells<br>
<br>
  As mentioned in 3.3, when a client Alice tells node Bob to extend<br>
  to node Carol, she needs to give Bob a fingerprint for Carol that Bob<br>
  will understand: one where Bob understands the digest algorithm, and<br>
  understands the identity key type.<br>
<br>
  There are two ways we can do this:<br>
<br>
    1) Alice&#39;s EXTEND cell contains every fingerprint for Carol that<br>
       Alice knows about.  Bob treats the cell as valid if every one he<br>
       can verify is correct.<br>
<br>
    2) Alice knows which fingerprint types Bob understands (either via<br>
       his version, or something else in his directory info).  She<br>
       selects a fingerprint for Carol using the best one of these<br>
       types.<br>
<br>
  The first seems more robust to me, if we have space for enough bytes.<br>
  If we proliferate too many types, though, we&#39;ll need to do the second.<br>
<br>
4. Directory changes<br>
<br>
4.1. Better cross-referencing<br>
<br>
  In some places, directory objects cross-reference one another by SHA1<br>
  hash.  They should use a better hash algorithm instead.<br>
<br>
  This does make problems in a few cases.<br>
<br>
  Router descriptors and extrainfo descriptors:<br>
<br>
     One problematic case is in determining node families.  If node A<br>
     and node B want to list each other as being in the same family,<br>
     they need to do so in a way that clients can interpret.  That could<br>
     mean listing SHA1-RSA1024 fingerprints so old clients understand,<br>
     AND new fingerprints for security. (But *that* could create<br>
     interesting partitioning attacks wherein your family looks<br>
     different depending on who&#39;s looking.)<br>
<br>
       Solution: we need to move the responsibility for combining node<br>
       families into the consensus voting process, so clients don&#39;t<br>
       need to understand the cross-reference types themselves.<br>
<br>
     Another case is in certifying extrainfo documents from descriptors.<br>
     For that, we can list multiple extrainfo digests, either on the<br>
     extrainfo line, or on additional lines.<br>
<br>
  Voting and consensus documents:<br>
<br>
     Adding more fingerprints in votes isn&#39;t a problem; votes are a tiny<br>
     fraction of authority bw usage.  Adding more hashes is easy.<br>
<br>
     For consensus documents, we ought to have flavors that you can<br>
     download depending on what set of fingerprint types you<br>
     understand.<br>
<br>
     For integrity purposes, consensuses can refer to microdescriptors<br>
     or descriptors by any digest type that the client understands.  But<br>
     for downloading purposes, the digest type must be one that<br>
     directory caches also support: see 4.4.<br>
<br>
4.2. More fingerprints<br>
<br>
  Because extending from node A to node B requires that we have node B&#39;s<br>
  fingerprint in a way that node A will understand, it is not enough to<br>
  get a set of identity fingerprints for each node in the format that<br>
  the client likes best -- see 3.3 and 3.4 above.  So every flavor of<br>
  consensus we serve needs to include a node identity in a format the<br>
  client understands, and node identities in formats such that every<br>
  node will understand at least one.<br>
<br>
4.3. An option: compound signatures on directory objects<br>
<br>
   In Tor 0.2.2.x and later, when we check a signature on a directory<br>
   object (not including hidden service descriptors), we only look at<br>
   the first DIGEST_LEN bytes of the RSA-signed data.  Once 0.2.1.x is<br>
   obsolete, or on any types of signatures not checked in 0.2.1.x, we<br>
   can use the rest of the space.  (We&#39;re using PKCS1 padding on our<br>
   signatures, which has an overhead of 11 bytes.  Signing a SHA1 hash<br>
   with a 1024-bit key therefore leaves 128-11-20==97 more bytes we<br>
   could use for a SHA2 or a SHA3 hash.)<br>
<br>
4.4. Downloading by digest<br>
<br>
   We should have directory caches support downloading objects by more<br>
   hash types.  Right now, descriptors are downloaded by their SHA1<br>
   hashes and microdescriptors by their SHA256 hashes.  This is okay for<br>
   now, but once SHA3 is out, we should support downloading all of these<br>
   by SHA3 digest.<br>
<br>
5. Link crypto changes<br>
<br>
  Currently we use TLS.  That&#39;s fine.<br>
<br>
  We should however look to longer link keys, bigger DH groups, etc.<br>
<br>
  Once TLS versions 1.1/1.2 are available in OpenSSL, we should move to<br>
  use them, I think.  We should also look into how quickly we can<br>
  deprecate TLS 1.0 and SSL &lt;= 3 usage.<br>
<br>
6. Relay crypto changes<br>
<br>
  There are a few things we might want out of improved relay crypto.<br>
  They include:<br>
   - Resistance to end-to-end bitwise tagging attacks.<br>
   - Better resistance to malleability.<br>
   - If using counter mode, no block-cipher operations on any value<br>
     known to the attacker.<br>
<br>
  I&#39;ll try to provide these in increasing order of difficulty.  None of<br>
  these is necessarily correct; I should look for a security proof or a<br>
  better construction for any that we seem likely to use.<br>
<br>
  Rationales: Our existing malleability resistance is a kludge.  Doing<br>
  no block-cipher ops on attacker-known values increases our security<br>
  margins a little.  Our arguments about tagging attacks hold that an<br>
  attacker who controls both ends has plenty of ways to win even if<br>
  tagging attacks are foiled; nonetheless, most of these ways are<br>
  technically slightly more difficult than xor-based tagging, and it<br>
  could be useful to boost our defense-in-depth a little bit, just in<br>
  case other active end-to-end attacks turn out to be harder than we&#39;d<br>
  thought.<br>
<br>
6.1. Option 1: Use AES-CTR in a less scary mode<br>
<br>
   When doing key expansion, in addition to establishing Kf, Kb, Df, and<br>
   Db, also establish IVf and IVb.  Use the current relay crypto, except<br>
   instead of starting the counters at 0, start them at IVf and IVb.<br>
   This way, an attacker doesn&#39;t have any known plaintexts to work with,<br>
   which makes AES a little more robust.<br>
<br>
6.2. Option 2: As 1, but tagging attacks garble the circuit after one block.<br>
<br>
   Keep an HMAC of all previously received encrypted cells on a circuit.<br>
   When decrypting a cell, use this HMAC value to determine the first 64<br>
   bits of the counter; increment the low 64 bits of the counter as<br>
   usual.<br>
<br>
   This way, if an adversary flips any bits before passing the stream<br>
   through an honest node, no _subsequent_ block will be recoverable.<br>
<br>
   To prevent any part of the stream from being re-used, close any<br>
   circuit if the low 64 bits of the counter would ever wrap (that is,<br>
   around 295 million terabytes).<br>
<br>
   (If we&#39;re using a stream cipher with fast re-key, then we can just<br>
   have the key used for each block be an HMAC of all previously<br>
   received ciphertext.)<br>
<br>
6.3. Option 3: As 1, but tagging attacks garble the circuit in the same block.<br>
<br>
   Use a large-block cipher mode, such as BEAR or LIONESS (depending on<br>
   whether we need a PRP or SPRP).  Base the key material for each block<br>
   on an HMAC of all previous blocks&#39; ciphertexts.<br>
<br>
   This way, if an adversary makes any alteration in a block, that block<br>
   and all subsequent blocks will be garbled.  It&#39;s more expensive than<br>
   2, though, especially if we need to use a LIONESS construction.<br>
<br>
   {I considered IGE here, with a trick where odd-numbered nodes on a<br>
   circuit start from the front of the block and even-numbered nodes<br>
   start from the end, but it didn&#39;t seem much better.  We should<br>
   investigate relative performance, though.}<br>
<br>
6.4. Option 4: Shall we have middle nodes be able to fast-stop bad data?<br>
<br>
   In all the above options, if a cell is altered, the middle node can<br>
   at best turn that cell and the rest of the cells on the circuit into<br>
   garbage, which the last node won&#39;t deliver (if honest) or can&#39;t<br>
   deliver (if dishonest).<br>
<br>
   Might we prefer to do as in mixnets, and have nodes kill circuits<br>
   upon receiving altered cells?<br>
<br>
   It&#39;s not such an obvious improvement.  Including more MACs is more<br>
   expensive in per-cell overhead.  The attacks that we would foil this<br>
   way but not with Option 3 are not so much better than the the passive or<br>
   timing-based-active end-to-end attacks that would still remain.<br>
<br>
   Consider that if option 3 is in place, an end-to-end attacker who<br>
   wants to do a tagging attack at one node can garble the rest of the<br>
   circuit and see if the output is garbled at the exit node.  But such<br>
   an attacker could just as easily close the circuit at one of those<br>
   nodes and watch for a corresponding close event, or even better --<br>
   simply pause traffic on that circuit for a while and watch for a<br>
   corresponding gap at the exit.  The only advantage of the garbling<br>
   attack would be that garbled cells are presumably rarer than circuit<br>
   closes or traffic pauses, and thus easier to use to distinguish<br>
   target circuits.  But that&#39;s still questionable: the other attacks<br>
   win fine, and the pause attack doesn&#39;t risk detection as much.<br>
<br>
   So why might we want to do this?  First, the overhead doesn&#39;t need to<br>
   be as bad as you might first expect (see below).  Second, it would be<br>
   nice to increase the security margin as much as possible: &quot;attacks<br>
   only get better&quot;.<br>
<br>
   So let&#39;s figure out how it would look.<br>
<br>
   To do this one, we&#39;d want to have outgoing and incoming circuits<br>
   treated differently.  Incoming cells would get decrypted as in 1<br>
   above, except that we&#39;d have a MAC on them.  For outgoing cells,<br>
   each node would check that the first N bytes of the cell<br>
   match a MAC of all data seen so far, *including the rest of the<br>
   cell*.  They&#39;d then remove the first N bytes, re-pad the cell<br>
   with bytes from a PRNG, and decrypt the resulting re-padded cell.<br>
   (This is basically how mixmaster works, and how mixminion works in<br>
   the common case.)<br>
<br>
   The space overhead here is kind of large: N bits per cell per node.<br>
   In the most paranoid case, if we used 256-bit HMACs on 3-node paths,<br>
   that&#39;s 96 bytes per cell, which is more than 20% of the total length.<br>
   But we can probably do better if we let the CREATE operation also<br>
   tell the node some N to check.  For example, the first node doesn&#39;t<br>
   need to check any bits.  The second and third nodes could check 64<br>
   bits apiece; that only has 16 bytes overhead total, and high<br>
   probability of catching any changes. (Birthday attacks don&#39;t matter<br>
   here, and an attacker who mounts this attack for long enough to<br>
   accidentally find a 64-bit MAC will break so many circuits in the<br>
   process as to become totally unreliable.)<br>
<br>
   All of this leaks the path lengths and position on the path to<br>
   various nodes.  We might open ourselves up to partitioning attacks if<br>
   different clients choose different numbers of bits.  What&#39;s more, we<br>
   might leak the length of the path to the last node by how much junk<br>
   there is at the end of the cell.  So we&#39;d need to be careful!<br>
<br>
   Here&#39;s a simple construction for this format, to be concrete:<br>
<br>
     The CREATE operation&#39;s KDF produces the following outputs:<br>
           Kf, IVf  (stream cipher key and IV for forward direction)<br>
           Kb, IVb  (stream cipher key and IV for reverse direction)<br>
           Mf       (MAC key for forward direction)<br>
           Mb       (MAC key for reverse direction)<br>
           SEEDf    (PRNG key for forward direction)<br>
     And it also sets the following user-selected parameter:<br>
           MACBYTESf (an integer between 0 and 32 inclusive)<br>
           MACBYTESb (an integer between 0 and 32 inclusive)<br>
           CANEXIT   (boolean: can we exit from this hop?)<br>
<br>
     Let Kf[i], Mf[i], etc denote the parameter Kf, Mf, etc as shared<br>
     between the client and the i&#39;th node in its circuit.<br>
<br>
     Relay cells sent towards the client have the following plaintext<br>
     format:<br>
         Body:<br>
           Content:<br>
             Relay Command [1 byte]<br>
             StreamID      [2 bytes]<br>
             Length        [2 bytes]<br>
             Data          [Up to CELL_DATA_LEN-5-MACBYTESb bytes]<br>
             Padding       [randomly generated as needed to fill the<br>
                            cell]<br>
           MAC(All previous encrypted content + encrypted content,<br>
                                  Mb)[:MACBYTESb]   [MACBYTESb bytes]<br>
<br>
     The originator of the client-bound cell encrypts the content with<br>
     the next part of its Kb,IVb stream, then appends the MAC.<br>
<br>
     Non-clients receiving a client-bound relay cell encrypt the entire<br>
     cell body, MAC included, with the next part of the stream cipher<br>
     that was keyed with Kb,IVb.<br>
<br>
     When the client receives a relay cell body, it iteratively does:<br>
<br>
       For node i in circuit from 1..N:<br>
           Let cells_i = all previous cells which we previously decided<br>
              were from node i, or relayed by node i,<br>
           and let cellbody = the body of the cell, except for the last<br>
              MACBYTESb[i] bytes,<br>
           and let cellmac = the last MACBYTESb[i] bytes of this cell.<br>
<br>
           If cellmac is nonempty, check wither cellmac = mac_received,<br>
           where mac_received is the first MACBYTESb[i] bytes of<br>
           MAC(cells_i | cellbody, Mb[i]). If so, this cell is from node<br>
           i.<br>
<br>
           If this cell is from node i, add cellbody to cells_i, then<br>
           decrypt cellbody using the stream keyed with Kb[i],IVb[i].<br>
           Act on it as a relay cell.<br>
<br>
           Otherwise add the entire cell to cells_i, and decrypt it, MAC<br>
           included, with the stream keyed with Kb[i], IVb[i].<br>
<br>
       If no node sent this cell: it&#39;s junk and somebody is probably<br>
       messing with us!  Destroy the circuit.<br>
<br>
<br>
     When the client *sends* a cell outbound to node N:<br>
<br>
         Let cells[i] start at &quot;&quot; for all i in 1...N initially, and get<br>
         updated as below.<br>
<br>
         Let MACLEN = SUM(MACBYTESf[1...N])<br>
<br>
         Let Body =<br>
             Relay Command [1 byte]<br>
             StreamID      [2 bytes]<br>
             Length        [2 bytes]<br>
             Data          [Up to CELL_DATA_LEN-5-MACLEN bytes]<br>
             Padding       [randomly generated,<br>
                            CELL_DATA_LEN-5-MACLEN-len(Data) bytes]<br>
<br>
         Let PAD[i] = the next MACBYTESf[i] bytes from the PRNG keyed<br>
         with SEEDf[i], for i in 1...N<br>
<br>
         Let STREAM[i] = the next CELL_DATA_LEN bytes of<br>
           the stream keyed by Kf[i],IV[i], for i in 1...N<br>
<br>
         Let PADSEEN[1] == &quot;&quot;<br>
<br>
         For i in 2...N:<br>
             Let L = len(PADSEEN[i-1]) + len(PAD[i-1])<br>
             Let PADSEEN[i] = (PADSEEN[i-1] | PAD[i-1]) xor<br>
                              STREAM[i-1][CELL_DATA_LEN-L:]<br>
<br>
         For i in N down to 1:<br>
<br>
            Let Encbody = Body xor STREAM[i][:len(Body)]<br>
            Let extra = &quot;RECOGNIZED&quot; if i == N, &quot;OK&quot; otherwise<br>
            Let cells[i] = cells[i] | Body | PADSEEN[i]<br>
            Let M = MAC(cells[i] | extra , Mf[i])<br>
<br>
            Let Body = M[:MACBYTESf[i]] | EncBody<br>
<br>
<br>
     To receive an outbound cell:<br>
<br>
         Let M be the first MACBYTESf bytes of the cell, let REST be the<br>
         rest of the cell, and let &quot;cells&quot; be all previous cells on this<br>
         circuit.  If CANEXIT, and M = MAC(cells|rest|&quot;RECOGNIZED&quot;,<br>
         Mb)[:MACBYTESf], and MACBYTESf &gt; 0, this cell is for us.  If M<br>
         = MAC(cells|rest|&quot;OK&quot;, Mb)[:MACBYTESf], this cell is not for<br>
         us, but is valid.  Otherwise, destroy the circuit.<br>
<br>
         Let PAD = the next MACBYTESf[i] bytes of the PRNG keyed with<br>
         SEEDf, and decrypt REST | PAD using the stream cipher keyed<br>
         with Kf,IVf.  If this cell is for us, act on it as a relay<br>
         cell.  Otherwise, relay it.<br>
<br>
     ANOTHER VARIANT:<br>
<br>
         If we restrict MACBYTESf values to range 0..HL/2, where HL is the<br>
         length of the MAC output, we can replace<br>
           MAC(x | &quot;RECOGNIZED&quot;)[:MACBYTESf] and MAC(x | &quot;OK&quot;)[:MACBYTESf]<br>
         with<br>
           MAC(x)[:MACBYTESf] and MAC(x)[HL-MACBYTESf:]<br>
<br>
     PICKING MACBYTESf,MACBYTESb.<br>
<br>
         We don&#39;t need to worry about birthday attacks:<br>
<br>
            Because we&#39;re using a MAC, only the parties who are making<br>
            the MACs could try to do a brute-force search for a<br>
            collision, but they have no reason to do so.<br>
<br>
            If a collision occurs accidentally, an adversary can&#39;t<br>
            substitute an earlier-seen cell for a later one with the<br>
            same MAC, since the MAC covers not only the cell, but all<br>
            previous cells on the circuit.<br>
<br>
         So 16 bytes is about the most we should ever do, given our<br>
         usual security parameters.  Let me moot the number 8 for<br>
         MACBYTESb.<br>
<br>
         For outbound cells, for any hop we can exit from, choosing<br>
         MACBYTESf=6 gets us the current security level.  For the first<br>
         hop, assuming we don&#39;t exit from it, choosing MACBYTESf=0 is<br>
         totally safe, since the link crypto guarantees that nothing was<br>
         corrupted on the way.<br>
<br>
         In general, to prevent an end-to-end tagging attack, it seems<br>
         sufficient to do something like setting MACBYTES=8 for the last<br>
         hop, and MACBYTES=8 for one hop in the middle.<br>
<br>
     OTHER VARIANTS:<br>
<br>
         Can we combine this approach with one of the approaches in 2 or<br>
         3 above to ensure that if corrupt data passes (because of our<br>
         use of truncated HMACs) it still corrupts the stream?<br>
<br>
         Can/should we use GCM or something here instead of separate<br>
         encrypt/hmac operations?  It doesn&#39;t seem that GCM per se would<br>
         apply without some tweaking, which we probably do not have the<br>
         expertise to do.<br>
<br>
    OVERHEAD NOTES:<br>
<br>
         When computing additional overhead with this method, note that<br>
         it lets us replace the old 4 byte &quot;digest&quot; field and the 2 byte<br>
         &quot;recognized&quot; field.<br>
<br>
         I note in passing that we need at most 9 bits for the length<br>
         field, and at most 6 bits for the command field, yet we&#39;re using a<br>
         total of 3 bytes for those 15 bits.  That&#39;s an opportunity to<br>
         save another byte.<br>
<br>
ACKS<br>
<br>
   Lots of the good ideas and concerns here are due to Robert Ransom.<br>
<br>
   Michael Stone helped some with &quot;relay option 4&quot; above.<br>
_______________________________________________<br>
tor-dev mailing list<br>
<a href="mailto:tor-dev@lists.torproject.org">tor-dev@lists.torproject.org</a><br>
<a href="https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev" target="_blank">https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>&quot;Those who would give up Essential Liberty to purchase a little Temporary Safety deserve neither  Liberty nor Safety.&quot;<br>-- Benjamin Franklin <br>
</div>