Proposal: ChaCha20 and ChaCha20-Poly1305 Cipher implementations

Jamil Nimeh jamil.j.nimeh at
Fri Jan 26 21:57:42 UTC 2018

Hi Bernd, thank you for the feedback!

On 01/25/2018 12:30 PM, Bernd Eckenfels wrote:
> You Hello,
> The spec should most likely mention AAD data as well and the 12 Byte 
> size of the nonce. And that the plaintext Limit is in blocks (and the 
> AAD Limit is a 64Bit counter)
Good point about AAD.  My code currently doesn't check to make sure the 
total AAD from each AAD update doesn't overflow the 64-bit length.  It 
definitely needs to and can be done pretty easily. Thanks for pointing 
that out.

In terms of nonce length checking, I'll have to handle it multiple 
ways.  For ChaCha20ParameterSpec, I can check it in the constructor and 
that's easy to do.  Because ChaCha20-Poly1305 will use IvParameterSpec, 
a check will need to be done in the init call.  If I handle it there I 
could avoid it in the ChaCha20ParameterSpec too, but it seems better to 
report an error sooner rather than later and I don't think it hurts to 
have the check in both places.

I will probably also need a similar check in ChaCha20Parameters when 
AP.init() is called with whatever encoding we're going with.
> (And yes there is no wrapping to be found, not even in RFC 8103 which 
> discusses key transport,)
Thanks for confirming our suspicions so far.
> Does it need to define what AP.getEncoded() format/OID looks like?
Let me work backward from your two points:

Are you referring to the use of an OID instead of a name for use with 
AP.getInstance()?  If so I'll need to look that up, but I agree that it 
needs to be called out in the specification.  Thank you for pointing 
that out.

Should we call out the encoding format?

It should.  I would expect the output for ChaCha20-Poly1305 to just be a 
DER-encoded OCTET STRING, so it would look something like
0x04 0x0C [insert 12 bytes here]

ChaCha20 is the one that concerns me, because I see no standardized 
encoding.  There are other algs that do SEQUENCES of octet strings and 
integers in varying orders, but of course the meanings of those differ.  
The ASN.1 that I'm currently encoding (because I wanted *something*) is:

     OCTET STRING (12 byte nonce)
     INTEGER (initial counter value)

What worries me a bit is what alg name to assign to it in the standard 
names document.  If I call it "ChaCha20" and then some standardized 
format is developed, then we have a potential conflict down the line as 
we make our AP conform to the new standard.  If I come up with another 
name (call it "FooFoo20" as a placeholder), then getEncoded("FooFoo20") 
could continue to provide that encoding into the future and leave room 
for a standardized encoding with the name "ChaCha20".  But what of the 
default?  Without a standardized format, does FooFoo20 become the 
default?  And when the standardized version becomes real then the 
default probably should change to ChaCha20's encoding and we have 
another behavioral change there. Neither of those alternatives really 
sit well with me.  I admit I don't have a good answer yet on this one.

> Gruss
> Bernd
> -- 
> _____________________________
> From: Jamil Nimeh <jamil.j.nimeh at>
> Sent: Donnerstag, Januar 25, 2018 6:31 PM
> Subject: Proposal: ChaCha20 and ChaCha20-Poly1305 Cipher implementations
> To: OpenJDK Dev list <security-dev at>
> Hello all,
> 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.
> 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.
>   * Instantiation
>       o 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.
>   * Initialization
>       o 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).
>       o For init/engineInit methods that take an
>         AlgorithmParameterSpec, ChaCha20 and ChaCha20-Poly1305 use
>         different APS classes.
>           + 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).
>           + 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.
>           + 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().
>   * Use
>       o 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).
>       o 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.
>       o The getOutputSize call will return the following
>           + ChaCha20: Same value as the submitted input size
>           + 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).
>       o 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.
>       o 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.
>       o Nonce reuse protection: For both ChaCha20 and
>         ChaCha20-Poly1305: we will not allow reuse of the same nonce
>         between two consecutive init() operations.
>   * KeyGenerator
>       o 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.
>       o 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.
>   * Other TBD/in-progress items
>       o 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.
>           + 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).
>           + 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).
>               # 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?
>   * Backporting
>       o 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.
>       o 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).
>       o Questions concerning how far back this will be backported and
>         in what timeframes are still TBD.
>   * Things that will not be part of this proposal...
>       o 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_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.
> 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.
> --Jamil

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the security-dev mailing list