<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>Hello all,</p>
    <p>This is a proposal to introduce the ChaCha20 and
      ChaCha20-Poly1305 cipher implementations into JDK.  At a high
      level, the plan is to include both ChaCha20-Poly1305 and the base
      ChaCha20 stream cipher into JDK as part of the SunJCE provider
      initially, and then add TLS cipher suites as a follow-on feature.</p>
    <p>Both algorithms will be CipherSpi implementations and will
      generally conform to the details of that API.  I will discuss
      below some of the details such as which flavors of init are
      supported, etc.</p>
    <ul>
      <li>Instantiation</li>
      <ul>
        <li>For ChaCha20 and ChaCha20-Poly1305, the simple name will
          suffice: either "ChaCha20" for the basic stream cipher or
          "ChaCha20-Poly1305" for AEAD mode will work.  You may however
          use the 3-element transform "ChaCha20/None/NoPadding" and
          "ChaCha20-Poly1305/None/NoPadding".  Any other type of
          transformation string will cause NoSuchAlgorithmException to
          be thrown.</li>
      </ul>
      <li>Initialization</li>
      <ul>
        <li>All three engineInit methods in the CipherSpi API will be
          supported.  Keys provided through the various Cipher init
          methods should have the algorithm String "ChaCha20" applied to
          it (case-insensitive).</li>
        <li>For init/engineInit methods that take an
          AlgorithmParameterSpec, ChaCha20 and ChaCha20-Poly1305 use
          different APS classes.</li>
        <ul>
          <li>ChaCha20 will have a new ChaCha20ParameterSpec which takes
            a nonce (byte[]) and a counter (int).  This class will have
            getter methods to return those values if desired (getNonce()
            and getBlockCounter(), respectively).</li>
          <li>ChaCha20-Poly1305 will use IvParameterSpec to provide the
            nonce.  The primary reason this is being used instead of
            ChaCha20ParameterSpec is in order to make backporting to
            earlier JDK releases possible.  Also there's no need to set
            a counter value, so it would end up being an ignored
            parameter.<br>
          </li>
          <li>For init calls where no AlgorithmParameterSpec or
            AlgorithmParameter has been provided, a random nonce will be
            set at initialization time.  the counter value will be set
            to 1.  The random nonce can be retrieved using the getIV()
            Cipher method or by using the getParameters() call and
            parsing the output from AlgorithmParameters.getEncoded().<br>
          </li>
        </ul>
      </ul>
      <li>Use</li>
      <ul>
        <li>ChaCha20 encrypt and decrypt operations would work as any
          stream cipher would - as many bytes of ciphertext are returned
          from an encrypt function as plaintext bytes submitted (and
          vice versa for decrypt).</li>
        <li>ChaCha20-Poly1305 operates in a similar fashion to other
          AEAD ciphers.  For encryption operations, as many bytes are
          returned as input submitted with the exception of the doFinal
          calls, which would return any remaining ciphertext plus an
          extra 16 bytes for the tag.  For decryption, individual update
          calls return no plaintext.  The plaintext is returned only
          after the last bytes of ciphertext are provided, the
          authentication tag is provided, and the doFinal call is made. 
          Once the authentication tag has been verified then the
          plaintext will be returned.</li>
        <li>The getOutputSize call will return the following</li>
        <ul>
          <li>ChaCha20: Same value as the submitted input size</li>
          <li>ChaCha20-Poly1305: For encrypt, the returned size will be
            the input size + 16 bytes for the tag.  For decryption, the
            returned size will be input length - 16 bytes, or zero
            (whichever is larger).</li>
        </ul>
        <li>Wrap and Unwrap: I have not been able to find a standardized
          wrap/unwrap format for ChaCha20 similar to RFC 3394 for AES. 
          Right now the wrap() and unwrap() methods just take the
          encoding of the key to be wrapped and encrypts or decrypts
          them respectively.  If anyone is aware of a wrapping format
          for ChaCha20 please let me know.  My searches have so far come
          up empty.</li>
        <li>Counter rollover protection will be enforced.  For ChaCha20
          and ChaCha20-Poly1305, the cipher will cease to process input
          once the 32-bit counter space has been exhausted.</li>
        <li>Nonce reuse protection: For both ChaCha20 and
          ChaCha20-Poly1305: we will not allow reuse of the same nonce
          between two consecutive init() operations.</li>
      </ul>
      <li>KeyGenerator</li>
      <ul>
        <li>There will be a new KeyGenerator algorithm called "ChaCha20"
          which will create a 32-byte key suitable for use in either
          ChaCha20 or ChaCha20-Poly1305 cipher instances.  If you use
          forms of the KeyGenerator.init() that take a variable key
          length and you do something other than 32 bytes then you'll
          have InvalidParameterException thrown at you.</li>
        <li>If you use a form of the init that takes an
          AlgorithmParameterSpec it will throw
          InvalidAlgorithmParameterSpecException.  This is similar in
          behavior to other KeyGenerators like the HmacSHA-2 family,
          ARCFOUR, RC2, and AES.<br>
        </li>
      </ul>
      <li>Other TBD/in-progress items</li>
      <ul>
        <li>ChaCha20Parameters: This will be added to
          com.sun.crypto.provider and will be able to provide an
          encoding for parameters used in ChaCha20 and ChaCha20-Poly1305
          ciphers.</li>
        <ul>
          <li>For ChaCha20-Poly1305, the default encoded form of the
            AlgorithmParameters will be the AEADChaCha20Poly1305Nonce
            from RFC 8103 section 3 (basically the nonce as an ASN.1
            OCTET STRING of 12 bytes).</li>
          <li>For ChaCha20 I have not been able to find a standardized
            encoding for ChaCha20 parameters.  For lack of an official
            format I currently have it encoding the parameters as a
            SEQUENCE of an OCTET STRING (the nonce) and an INTEGER (the
            counter starting value).</li>
          <ul>
            <li>Question: If a getParameters call on a cipher is called
              after the cipher has been in use for some time, should
              such an encoding provide the counter's current value, or
              the starting value at the time the cipher was initialized?</li>
          </ul>
        </ul>
      </ul>
      <li>Backporting</li>
      <ul>
        <li>We would like to backport this, but because we need the new
          ChaCha20ParameterSpec class to set the initial counter value
          ChaCha20 will not get backported.</li>
        <li>ChaCha20-Poly1305 however can be backported, and the use of
          IvParameterSpec with ChaCha20-Poly1305 will allow this to
          happen.  Being able to backport ChaCha20-Poly1305 also allows
          the TLS cipher suites to be backported when those get added
          (see below).</li>
        <li>Questions concerning how far back this will be backported
          and in what timeframes are still TBD.<br>
        </li>
      </ul>
      <li>Things that will not be part of this proposal...</li>
      <ul>
        <li>TLS Cipher suites: Yes, we will do this, but this will be
          done as follow-on work.  This proposal covers just the JCA
          portion.  I've already got
          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, and
          TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 cipher suites
          working, so worry not!  It is our plan to have these in JSSE.</li>
      </ul>
    </ul>
    <p>Thanks to everyone who has provided feedback so far and let's set
      a closure date on the discussion for two weeks from now.  I think
      we should be able to hammer out any questions/concerns within that
      timeframe.<br>
    </p>
    <p>--Jamil<br>
    </p>
  </body>
</html>