Subject: [Cfrg] RFC Draft: PASETO - Platform-Agnotic SEcurity TOkens

From: Scott Arciszewski <[email-masked]>
Date: Thu, 19 Apr 2018 10:13:31 -0400

Dear IETF mailing list members,

There have been many real-world failures of the JOSE family of Internet
Standards since they were published in RFCs 7515-7520.

- Accepting {"alg":"none"} in many implementations allowed attackers to
bypass the protections that JWS were supposed to provide.
- Substituting RS256 with HS256 and using the RSA public key as an HMAC
secret key allowed trivial token forgery.
- JWE with ECIES fell to invalid curve attacks.

I've outlined these criticisms and more in a post titled "No way JOSE!
Javascript Object Signing and Encryption is a Bad Standard That Everyone
Should Avoid" [1] last year.

In addition to the critical vulnerabilities in the JOSE standards, there
are a lot of cryptographic smells to be found, especially in related
standards. Let me give you a brief, concrete example.

Recently, the W3C specification for WebAuthn was circulated on social
media. Upon closer review, it uses COSE (CBOR Object Signing and
Encryption-- a JOSE derivative), which requests the registration of two
classes of public-key signature algorithms [2]:

1. RSA with PCKS1v1.5
2. ECDAA, whose formal definition eschews the use of deterministic nonces [3]
and thereby fails to provide the protection of e.g. RFC 6979

There are a few lessons that I believe we can take away from these facts:

1. User-friendly standards like JOSE are incredibly influential in future
protocol designs.
2. If the decision to design cryptography protocols and/or decide the
primitives used is left to library designers and/or users, rather than
cryptography engineers, they will inevitably choose something dangerous or
terrifying.

There is an elegant solution to this trap we've found ourselves in: Design
an alternative token standard that avoids all of the design deficits that
plague the incumbent standard, but is still easy to use for at least 90% of
the JOSE/COSE use-cases. With that in mind, I'd like to present PASETO.

The first RFC draft is online [4]. As of this writing, we have 11
implementations in 10 different programming languages. [5]

The biggest change from JWT to PASETO is that, instead of an alg header
that MUST be understood and processed by implementations in JWT (which
allows different algorithms to be specified in the attacker-provided token)
in PASETO we use versioned protocols.

* If you're using v1, you're using AES-CTR+HMAC-SHA384 or RSASSA-PSS with
MGF1+SHA384, SHA384, and e=65537.
* If you're using v2, you're using XChaCha20-Poly1305 or Ed25519.

Future versions should be defined by cryptography experts.

Thank you for your time and please let me know if you have any immediate
feedback. If you would like to contribute to the next iteration of the RFC
draft, we're handling this on Github [6].

Note: I'm sending this to the JOSE and CFRG mailing lists. We don't yet
have a Working Group for this project. I'm unsure if a separate one should
be formed or if an existing one would like to contribute to the review and
refinement of this proposed Internet Standard.

[1]: https://paragonie.com/blog/2017/03/jwt-json-web-tokens-
is-bad-standard-that-everyone-should-avoid
[2]: https://www.w3.org/TR/2018/CR-webauthn-20180320/#sctn-cose-alg-reg
[3]: https://fidoalliance.org/specs/fido-uaf-v1.1-id-
20170202/fido-ecdaa-algorithm-v1.1-id-20170202.html#ecdaa-sign
[4]: https://datatracker.ietf.org/doc/draft-paragon-paseto-rfc
[5]: https://paseto.io
[6]: https://github.com/paragonie/paseto/blob/master/docs/RFC/paseto.md

Scott Arciszewski
Chief Development Officer
Paragon Initiative Enterprises
​​
<https://paragonie.com/>

---

From: Neil Madden <[email-masked]>
Date: Thu, 19 Apr 2018 23:03:31 +0100

I agree with some of the criticisms of JOSE here, but I have some concerns about the proposed replacement.

Firstly, your blog post states that ECDH in JOSE is only defined for NIST curves. Actually, RFC 8037 [1] defined X25519/X448 for ECDH in JWE and EdDSA for JWS.

Thomas Ptacek also had some good observations about weaknesses of the JOSE standards [2]. 

Two questions then occur to me:
1. Is JOSE fixable or does it need to be replaced entirely?
2. If it needs to be replaced, is PASETO a suitable replacement?

I’ll tackle these in reverse order. I find PASETO interesting, but also find aspects of the design somewhat confusing:

- The basic encryption construction [3] appears (to me at least) to be a novel design based on three passes over the message: once to generate a pseudorandom nonce in an SIV-like construction (but not actually authenticating the message), a second time to encrypt, and then a third time to authenticate the cipher text. Is this a well-studied design? What security goal is it designed to meet? Why not just use SIV mode?

- PASETO still relies on the message to tell it the type of crypto algorithms in use: “v1.local” vs “v1.public” vs “v2.local” etc. Isn’t this “alg” again, but with a more restricted (and higher-level) set of algorithms? I don’t think this is necessary at all - see below for an alternative.

- There are some odd combinations of security levels defined. For instance, v1.local uses untruncated HMAC-SHA384 for authentication (384-bit tag), while v2.local uses Poly1305 (128-bit tag) - so v2 is actually targeting a lower security level for authentication? 

- XChaCha20 has not been formally published before. While it seems an “obvious” translation of XSalsa20 to ChaCha20, I’d prefer that to be independently specified (e.g. by CFRG) before being the recommended choice. XSalsa20 is already published and well known.

- The guidelines in section 3.1 are unclear. For instance, they state that long nonces (> 128 bits) satisfy “some degree of nonce-misuse resistance”, but they do not - at least not in the sense of misuse-resistant authenticated encryption (MRAE). They just make randomly-generated nonces less likely to collide. The security goals should be clearly defined here.

- The guidelines state that public key encryption should be IND-CCA2, but public key encryption is not defined in the spec. It’s not clear that IND-CCA2 is the right security goal here, vs e.g. public key authenticated encryption as in NaCl.

So while I appreciate the streamlined design compared to JOSE, there are enough non-obvious design decisions here that I am reluctant to immediately recommend it as a replacement for JOSE.

But is JOSE fixable instead? I think there is certainly a lot you could do to improve it without completely throwing it away and starting again. The problem is that old standards never really get thrown away, so we end up supporting n+1 standards instead. I think a few basic changes could improve the standards considerably:

1. Deprecating broken/dubious algorithms (like RSA encryption with PKCS#1 v1.5 padding) and proposing modern and robust replacements (like RFC 8037 or my own draft for SIV modes [4]).
2. Moving the “alg” and “enc” headers out of JWE/JWS and instead into JWK so that is the key that determines the algorithm not the message.
3. Deprecating all the ways that you can specify a key in a message, leaving just “kid”.

I think these changes would go quite a long way to making JOSE more robust. It wouldn’t solve everything (and I have more suggestions for another time), but it moves in the right direction. Ultimately I would like JWE to gravitate towards authenticated encryption in both symmetric and public-key settings, and JWS to concentrate on non-repudiation, but that is a larger change.

[1] https://tools.ietf.org/html/rfc8037
[2] https://lobste.rs/s/r4lv76/jwt_is_bad_standard_everyone_should_avoid#c_k91fsa
[3] https://tools.ietf.org/html/draft-paragon-paseto-rfc-00#section-4.3.2
[4] https://tools.ietf.org/html/draft-madden-jose-siv-mode-02

Regards,

Neil Madden

> On 19 Apr 2018, at 15:13, Scott Arciszewski <[email-masked]> wrote:
> 
> There have been many real-world failures of the JOSE family of Internet Standards since they were published in RFCs 7515-7520.
> 
> - Accepting {"alg":"none"} in many implementations allowed attackers to bypass the protections that JWS were supposed to provide.
> - Substituting RS256 with HS256 and using the RSA public key as an HMAC secret key allowed trivial token forgery.
> I've outlined these criticisms and more in a post titled "No way JOSE! Javascript Object Signing and Encryption is a Bad Standard That Everyone Should Avoid" [1] last year. 
> 
> In addition to the critical vulnerabilities in the JOSE standards, there are a lot of cryptographic smells to be found, especially in related standards. Let me give you a brief, concrete example.
> 
> Recently, the W3C specification for WebAuthn was circulated on social media. Upon closer review, it uses COSE (CBOR Object Signing and Encryption-- a JOSE derivative), which requests the registration of two classes of public-key signature algorithms [2]:
> 
> 1. RSA with PCKS1v1.5
> 2. ECDAA, whose formal definition eschews the use of deterministic nonces [3] and thereby fails to provide the protection of e.g. RFC 6979
> 
> 1. User-friendly standards like JOSE are incredibly influential in future protocol designs.
> 2. If the decision to design cryptography protocols and/or decide the primitives used is left to library designers and/or users, rather than cryptography engineers, they will inevitably choose something dangerous or terrifying.
> 
> There is an elegant solution to this trap we've found ourselves in: Design an alternative token standard that avoids all of the design deficits that plague the incumbent standard, but is still easy to use for at least 90% of the JOSE/COSE use-cases. With that in mind, I'd like to present PASETO.
> 
> The first RFC draft is online [4]. As of this writing, we have 11 implementations in 10 different programming languages. [5]
> 
> The biggest change from JWT to PASETO is that, instead of an alg header that MUST be understood and processed by implementations in JWT (which allows different algorithms to be specified in the attacker-provided token) in PASETO we use versioned protocols.
> 
> * If you're using v1, you're using AES-CTR+HMAC-SHA384 or RSASSA-PSS with MGF1+SHA384, SHA384, and e=65537.
> Thank you for your time and please let me know if you have any immediate feedback. If you would like to contribute to the next iteration of the RFC draft, we're handling this on Github [6].
> 
> Note: I'm sending this to the JOSE and CFRG mailing lists. We don't yet have a Working Group for this project. I'm unsure if a separate one should be formed or if an existing one would like to contribute to the review and refinement of this proposed Internet Standard.
> 
> [1]: https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid
> [3]: https://fidoalliance.org/specs/fido-uaf-v1.1-id-20170202/fido-ecdaa-algorithm-v1.1-id-20170202.html#ecdaa-sign
> [4]: https://datatracker..ietf.org/doc/draft-paragon-paseto-rfc
> [5]: https://paseto.io
> Paragon Initiative Enterprises​​
> 
> _______________________________________________
> Cfrg mailing list
> [email-masked]
> https://www.irtf.org/mailman/listinfo/cfrg

---

From: "Salz, Rich" <[email-masked]>
Date: Thu, 19 Apr 2018 22:41:54 +0000

>    - The basic encryption construction [3] appears (to me at least) to be a novel design

And for that reason alone, we should throw this away.

---

From: Neil Madden <[email-masked]>
Date: Fri, 20 Apr 2018 11:49:02 +0100

Comments inline below.

> On 20 Apr 2018, at 03:33, Scott Arciszewski <[email-masked]> wrote:
> 
> Hi Neil,
> 
> That's great. This was not known to me when I wrote the blog post in March 2017.
> 
> I'm curious: Which libraries implement RFC 8037 and eschew the foot-gun public key cryptography protocols?
> 
> If RFC 8037 adoption has reached 100% of libraries and protocols that implement JOSE standards, and none of them speak RSA-PKCS1v1.5 or non-deterministic ECDSA with a NIST curve anymore, I'll need to reevaluate my position on JOSE at the ecosystem level. Otherwise, JOSE's legacy of being an error-prone cryptographic standard is still rather damning at the ecosystem level, and the only effective means of fixing that is to replace the entire standard with something not-broken.

I think you are overestimating the effectiveness of this strategy. Unfortunately, insecure implementations of old standards don’t go away because you introduce a new standard.

> 
> >​ ​- The basic encryption construction [3] appears (to me at least) to be a novel design based on three passes over the message: once to generate a pseudorandom nonce in an SIV-like construction (but not actually authenticating the message), a second time to encrypt, and then a third time to authenticate the cipher text. Is this a well-studied design? What security goal is it designed to meet?
> 
> The v1 construction is literally CTR+HMAC. It uses HKDF for key splitting (which is what HKDF was meant for). It uses SHA384 so only one hash function needs to be implemented. (SHA384 was chosen due to it being the best of the SHA2 variants available in e.g. PHP 7.0 that's immune to length-extension attacks.) Furthermore, v1 uses PSS instead of PKCS1v1.5 because PKCS1v1.5 is a terrible idea.
> 
> What you're calling an SIV-like construction is just part of the nonce/HKDF-salt generation scheme for v1. Its purpose is to add a safeguard in case someone implements it against an insecure RNG such as OpenSSL's RAND_bytes() (which is not fork-safe and might repeat outputs, which would be catastrophic for CTR mode). If an implementation eschewed that and just did /dev/urandom here, it wouldn't affect much since the nonce provided in the actual token is what's used to decrypt. As long as HMAC-SHA384 is collision-resistant, it will serve its purpose of avoiding nonce-reuse conditions and otherwise isn't that important.

Don’t get me wrong, I think this is a nice idea, but it’s also sufficiently novel that I don’t feel comfortable saying that PASETO v1.local is “just” CTR+HMAC with a few minor tweaks. The HMAC key for the GetNonce() function is coming from the PRNG that you do not trust because it may be biased, poorly designed, etc. If you look at the design of HKDF, it puts potentially biased source key material in the (non-key) input to HMAC and uses either a fixed/empty constant or an (unbiased) random salt as the key. Part of the rationale is given on page 19 of [1]:

“[…] PRFs are specifically designed to remain secure even when the inputs (except for the key) are fully known and correlated, or even adversarially chosen.”

So what can we conclude about the pseudorandom collision resistance of the output of HMAC when the *key* comes from a potentially biased/untrusted source? I’m not a cryptographer, so maybe that is still fine, but I don’t know if you could prove it without making non-standard assumptions about HMAC.

[1] https://eprint.iacr.org/2010/264.pdf

> 
> AES-CTR then HMAC-SHA2 is a pretty simple and well-studied construction, although AES-CBC is more common than AES-CTR. We find it simpler to implement CTR mode safely in real world systems that only give you ECB mode out of the box, without introducing e.g. padding-related bugs.
> 
> ​> Why not just use SIV mode?
> 
> Open up the crypto interfaces exposed in any three of the most used programming languages on the Internet today. You can be biased and pick your favorites, as long as they power >= 1% of the Internet and aren't something totally obscure. Then tell me which among them offer SIV mode.

From a quick survey:

 - OpenSSL is adding support for AES-SIV [2], apparently because it is planned to be mandatory to implement for NTP security [3].
 - BoringSSL supports AES-GCM-SIV [4] (admittedly this is not quite a straightforward application of SIV mode).
 - Google Tink supports AES-SIV [5] on Java (& Android) with Go, C++, Objective-C in development/planned (I believe), and Javascript and C# ports “in the works".

[2] https://github.com/openssl/openssl/pull/3540
[3] https://tools.ietf.org/html/draft-ietf-ntp-using-nts-for-ntp-11.html
[4] https://github.com/google/boringssl/blob/master/include/openssl/aead.h
[5] https://github.com/google/tink/blob/master/doc/PRIMITIVES.md#deterministic-authenticated-encryption-with-associated-data

> 
> Protocol v1 literally only exists for systems that use e.g. OpenSSL and cannot, for political or technical reasons, use something like NaCl, libsodium, HaCl, etc.

AES-SIV itself is a relatively straight-forward composition of AES-CMAC (or another MAC) and AES-CTR, which are widely available building blocks.

> 
> > - PASETO still relies on the message to tell it the type of crypto algorithms in use: “v1.local” vs “v1.public” vs “v2.local” etc. Isn’t this “alg” again, but with a more restricted (and higher-level) set of algorithms? I don’t think this is necessary at all - see below for an alternative. ​
> 
> There is one advantage to what we're doing here (v1.local vs v2.local) over what JOSE does: Instead of library designers or users being able to mix-and-match cryptography protocols, they choose their version and purpose and the rest of the details are decided for them.
> 
> No knobs, no levers, no corner cases where someone accidentally deploys e=d=1 RSA [1]. Instead, they get one simple, misuse-resistant standard that solves their needs without any surprises.

Right, but you could write an RFC that proposes 4 new JOSE algorithms: “v1.local”, “v1.public”, “v2.local”, “v2.public” and marks all others (and associated headers) as prohibited. Wouldn’t that be pretty similar to the core of PASETO? The fundamental problem with “alg” in JOSE is that it requires you to trust the message to tell you what algorithm to use to validate that message. PASETO makes exactly the same mistake, it just has a much better (and much smaller) algorithm selection. 

[snip]

I think the work you are doing on PASETO is valuable and has a lot of nice ideas. I would also say that is already better than JOSE as it currently is, but I’m not sure it is the best replacement.

Kind regards,

Neil

---

From: Carsten Bormann <[email-masked]>
Date: Fri, 20 Apr 2018 13:03:08 +0200

On Apr 20, 2018, at 12:49, Neil Madden <[email-masked]> wrote:
> 
> insecure implementations of old standards don’t go away because you introduce a new standard

Exactly.

If we have to invent a new standard each time an existing standard is implemented with a security flaw, we have a lot of work to do.

Insecure implementations exist even of standards such as TLS.  Usually the strategy is to fix the implementations.  (It is also a good idea to envision what implementers will mess up when creating a new standard.  But there are limits to that approach.)

One of the objectives in the definition of COSE was to avoid some of the pitfalls of JOSE.
There is also work ongoing to document the security considerations of JOSE better, e.g., draft-ietf-oauth-jwt-bcp.

I’d like to focus the energy that appears to be visible here on agreeing good SIV constructions and getting them registered with COSE.

Grüße, Carsten

---

From: Vladimir Dzhuvinov <[email-masked]>
Date: Fri, 20 Apr 2018 14:14:44 +0300

> 2. Moving the “alg” and “enc” headers out of JWE/JWS and instead into JWK so that is the key that determines the algorithm not the message.
Developers letting the "alg" header alone drive JWS / JWE processing is
the most glaring mistake I keep seeing. JOSE library maintainers can
possibly help here, by hiding the "alg" header from developers :)

We took a similar measure with "alg":"none", by giving those JOSE
objects a different class than JWS (for type safety) which cannot be
validated.

Vladimir

---

From: Mike Jones <[email-masked]>
Date: Fri, 20 Apr 2018 15:18:04 +0000

The JWT Best Current Practices (BCP) draft catalogs the different implementation mistakes that have been documented and describes how not make them.  The timing of this discussion is good because the draft is currently in working group last call - through Monday, April 30th.  Have a look at https://tools.ietf.org/html/draft-ietf-oauth-jwt-bcp-01.  If you believe that additional content is needed, please send your reviews to [email-masked].

Also, see Neil Madden's draft https://tools.ietf.org/html/draft-madden-jose-siv-mode-02 on misuse-resistant cryptography for JOSE.  I've encouraged him to take it forward.  Please provide feedback on that as well.

				-- Mike

-----Original Message-----
From: Cfrg <[email-masked]> On Behalf Of Carsten Bormann
Sent: Friday, April 20, 2018 4:03 AM
To: Neil Madden <[email-masked]>
Cc: [email-masked]; [email-masked]
Subject: Re: [Cfrg] [jose] RFC Draft: PASETO - Platform-Agnotic SEcurity TOkens

Exactly.

Grüße, Carsten

---

From: David Adrian <[email-masked]>
Date: Mon, 23 Apr 2018 13:44:00 +0000

> If we have to invent a new standard each time an existing standard is
implemented with a security flaw, we have a lot of work to do.

You fundamentally cannot fix a standard with unusable to the point of
broken negotiation by extending the negotiation. If you don't want PASETO
to be a new standard, call it JOSEv3.

On Fri, Apr 20, 2018 at 11:18 AM Mike Jones <Michael.Jones=
[email-masked]> wrote:

> The JWT Best Current Practices (BCP) draft catalogs the different
> implementation mistakes that have been documented and describes how not
> make them.  The timing of this discussion is good because the draft is
> currently in working group last call - through Monday, April 30th.  Have a
> look at https://tools.ietf.org/html/draft-ietf-oauth-jwt-bcp-01.  If you
> believe that additional content is needed, please send your reviews to
> [email-masked].
>
> Also, see Neil Madden's draft
> https://tools.ietf.org/html/draft-madden-jose-siv-mode-02 on
> misuse-resistant cryptography for JOSE.  I've encouraged him to take it
> forward.  Please provide feedback on that as well.
>
>                                 -- Mike
>
> If we have to invent a new standard each time an existing standard is
> implemented with a security flaw, we have a lot of work to do.
>
> Insecure implementations exist even of standards such as TLS.  Usually the
> strategy is to fix the implementations.  (It is also a good idea to
> envision what implementers will mess up when creating a new standard.  But
> there are limits to that approach.)
>
> I’d like to focus the energy that appears to be visible here on agreeing
> good SIV constructions and getting them registered with COSE.
>
> Grüße, Carsten
>
-- 
David Adrian
https://dadrian.io

---

From: Neil Madden <[email-masked]>
Date: Mon, 23 Apr 2018 17:43:25 +0100

> On 23 Apr 2018, at 14:44, David Adrian <[email-masked]> wrote:
> 
> You fundamentally cannot fix a standard with unusable to the point of broken negotiation by extending the negotiation. If you don't want PASETO to be a new standard, call it JOSEv3.

I don’t believe that PASETO is actually fundamentally different from JOSE in this respect. Is there a meaningful distinction between v1.local.<token> and {“alg”:”v1.local”}.<token> ?

One of the critical vulnerabilities historically in JOSE implementations was [1], whereby if an implementation was using RSA signed JWTs an attacker could get the server’s public key and use it as if it was a HMAC key to produce a forged JWT with {“alg”:”HS256”} in the header. If the JWT library just provided a verify(String jwt, Key key) function then it might be tricked into using the attacker’s choice of algorithm (HS256) with the server’s RSA public key and the JWT would validate. Oops!

This flaw has been rightly criticised, including by the authors of PASETO. Don’t let the attacker chose the algorithm!

But wait, aren’t PASETO implementations potentially vulnerable to *exactly the same vulnerability*?! If my server is set up to use v2.public (Ed25519) signed PASETO tokens, what is to stop an attacker grabbing my Ed25519 public key (which is a 32 byte value) and using it to create a PASETO token using v2.local? Recall that v2.local takes a 32 byte symmetric key. If the PASETO library just has a function verify(String paseto, Key key) and looks at the header to decide how to process the token, then it will have exactly the same vulnerability that those JOSE libraries had. So how does PASETO the spec make this vulnerability less likely?

Looking at the reference implementation [2], it seems that if the library user didn’t set an allowed purpose then the only thing stopping this is a type check on the public key class. In other words, the implementor took extra safe-guards beyond those documented in the specification. Phew!

Am I missing something here? As far as I can tell, the PASETO docs and draft RFC don’t even mention this as a consideration. How is this better than JOSE?

[1] https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
[2] https://github.com/paragonie/paseto/blob/master/src/Parser.php#L159

Neil

---

From: Mike Jones <[email-masked]>
Date: Mon, 23 Apr 2018 17:43:52 +0000

I realize that, as described in https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/, some libraries did allow a RSA public key value to be used as an HMAC key.  As I see it, this is a problem with those implementations - not with the specification.  RSA public keys don't even have the same syntax as HMAC keys! (The former has "e" and "n" values and "kty":"RSA" and the latter has a "k" value and "kty":"oct".)  An implementation that would allow the two to be used interchangeably isn't even providing type safety - let alone security.  Note that this implementation problem is already also covered in https://tools.ietf.org/html/draft-ietf-oauth-jwt-bcp-01#section-3.1.

The fact that there have been implementation bugs isn't overly surprising.  That happens in all code.  This, to me, makes the case that we should have good public test suites for JWS/JWE/JWT implementations to ferret out these bugs - just like we have the OpenID Certification test suite http://openid.net/certification/ for OpenID Connect implementations.  Whereas changing to a different standard would just result in different bugs, and would reduce interoperability.

				-- Mike

-----Original Message-----
From: jose <[email-masked]> On Behalf Of Neil Madden
Sent: Monday, April 23, 2018 9:43 AM
To: David Adrian <[email-masked]>
Cc: Carsten Bormann <[email-masked]>; [email-masked]; Mike Jones <Michael.Jones=[email-masked]>; [email-masked]
Subject: Re: [jose] [Cfrg] RFC Draft: PASETO - Platform-Agnotic SEcurity TOkens

Neil
_______________________________________________
jose mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/jose

---

From: Neil Madden <[email-masked]>
Date: Mon, 23 Apr 2018 19:13:45 +0100

A public test suite along the lines of Project Wycheproof [1] for known vulnerabilities would be extremely valuable in my opinion.

[1] https://github.com/google/wycheproof

Neil

> On Monday, Apr 23, 2018 at 6:43 pm, Mike Jones <[email-masked] (mailto:[email-masked])> wrote:

---

From: Scott Arciszewski <[email-masked]>
Date: Mon, 23 Apr 2018 15:00:03 -0400

This is an excellent point that will be rectified in the documentation and
future drafts of the RFC.

How is this better than JOSE? It's better in that it's a first draft, not a
final specification. :P

Scott Arciszewski
Chief Development Officer
Paragon Initiative Enterprises <https://paragonie.com>

On Mon, Apr 23, 2018 at 12:43 PM, Neil Madden <[email-masked]>
wrote:

> I don’t believe that PASETO is actually fundamentally different from JOSE
> in this respect. Is there a meaningful distinction between v1.local.<token>
> and {“alg”:”v1.local”}.<token> ?
>
> One of the critical vulnerabilities historically in JOSE implementations
> was [1], whereby if an implementation was using RSA signed JWTs an attacker
> could get the server’s public key and use it as if it was a HMAC key to
> produce a forged JWT with {“alg”:”HS256”} in the header. If the JWT library
> just provided a verify(String jwt, Key key) function then it might be
> tricked into using the attacker’s choice of algorithm (HS256) with the
> server’s RSA public key and the JWT would validate. Oops!
>
> This flaw has been rightly criticised, including by the authors of PASETO.
> Don’t let the attacker chose the algorithm!
>
> But wait, aren’t PASETO implementations potentially vulnerable to *exactly
> the same vulnerability*?! If my server is set up to use v2.public (Ed25519)
> signed PASETO tokens, what is to stop an attacker grabbing my Ed25519
> public key (which is a 32 byte value) and using it to create a PASETO token
> using v2.local? Recall that v2.local takes a 32 byte symmetric key. If the
> PASETO library just has a function verify(String paseto, Key key) and looks
> at the header to decide how to process the token, then it will have exactly
> the same vulnerability that those JOSE libraries had. So how does PASETO
> the spec make this vulnerability less likely?
>
> Looking at the reference implementation [2], it seems that if the library
> user didn’t set an allowed purpose then the only thing stopping this is a
> type check on the public key class. In other words, the implementor took
> extra safe-guards beyond those documented in the specification. Phew!
>
> Am I missing something here? As far as I can tell, the PASETO docs and
> draft RFC don’t even mention this as a consideration. How is this better
> than JOSE?
>

---

From: Scott Arciszewski <[email-masked]>
Date: Thu, 19 Apr 2018 22:33:19 -0400

Hi Neil,

Firstly, your blog post states that ECDH in JOSE is only defined for NIST
> curves. Actually, RFC 8037 [1] defined X25519/X448 for ECDH in JWE and
> EdDSA for JWS.
>
>
That's great. This was not known to me when I wrote the blog post in March
2017.

I'm curious: Which libraries implement RFC 8037 and eschew the foot-gun
public key cryptography protocols?

If RFC 8037 adoption has reached 100% of libraries and protocols that
implement JOSE standards, and none of them speak RSA-PKCS1v1.5 or
non-deterministic ECDSA with a NIST curve anymore, I'll need to reevaluate
my position on JOSE at the ecosystem level. Otherwise, JOSE's legacy of
being an error-prone cryptographic standard is still rather damning at the
ecosystem level, and the only effective means of fixing that is to replace
the entire standard with something not-broken.

​
> ​
> - The basic encryption construction [3] appears (to me at least) to be a
> novel design based on three passes over the message: once to generate a
> pseudorandom nonce in an SIV-like construction (but not actually
> authenticating the message), a second time to encrypt, and then a third
> time to authenticate the cipher text. Is this a well-studied design? What
> security goal is it designed to meet?
>
>
The v1 construction is literally CTR+HMAC. It uses HKDF for key splitting
(which is what HKDF was meant for). It uses SHA384 so only one hash
function needs to be implemented. (SHA384 was chosen due to it being the
best of the SHA2 variants available in e.g. PHP 7.0 that's immune to
length-extension attacks.) Furthermore, v1 uses PSS instead of PKCS1v1.5
because PKCS1v1.5 is a terrible idea.

What you're calling an SIV-like construction is just part of the
nonce/HKDF-salt generation scheme for v1. Its purpose is to add a safeguard
in case someone implements it against an insecure RNG such as OpenSSL's
RAND_bytes() (which is not fork-safe and might repeat outputs, which would
be catastrophic for CTR mode). If an implementation eschewed that and just
did /dev/urandom here, it wouldn't affect much since the nonce provided in
the actual token is what's used to decrypt. As long as HMAC-SHA384 is
collision-resistant, it will serve its purpose of avoiding nonce-reuse
conditions and otherwise isn't that important.

AES-CTR then HMAC-SHA2 is a pretty simple and well-studied construction,
although AES-CBC is more common than AES-CTR. We find it simpler to
implement CTR mode safely in real world systems that only give you ECB mode
out of the box, without introducing e.g. padding-related bugs.

​ Why not just use SIV mode?
Open up the crypto interfaces exposed in any three of the most used
programming languages on the Internet today. You can be biased and pick
your favorites, as long as they power >= 1% of the Internet and aren't
something totally obscure. Then tell me which among them offer SIV mode.

Protocol v1 literally only exists for systems that use e.g. OpenSSL and
cannot, for political or technical reasons, use something like NaCl,
libsodium, HaCl, etc.

- PASETO still relies on the message to tell it the type of crypto
> algorithms in use: “v1.local” vs “v1.public” vs “v2.local” etc. Isn’t this
> “alg” again, but with a more restricted (and higher-level) set of
> algorithms? I don’t think this is necessary at all - see below for an
> alternative. ​
>
>
There is one advantage to what we're doing here (v1.local vs v2.local) over
what JOSE does: Instead of library designers or users being able to
mix-and-match cryptography protocols, they choose their version and purpose
and the rest of the details are decided for them.

No knobs, no levers, no corner cases where someone accidentally deploys
e=d=1 RSA [1]. Instead, they get one simple, misuse-resistant standard that
solves their needs without any surprises.

​
> ​
> - There are some odd combinations of security levels defined. For
> instance, v1.local uses untruncated HMAC-SHA384 for authentication (384-bit
> tag), while v2.local uses Poly1305 (128-bit tag) - so v2 is actually
> targeting a lower security level for authentication?
>

As said above, this design decision was motivated by having one single hash
function used for all operations. SHA384 was chosen because other
developers might try to badly mimic the design decisions made in PASETO and
I'd rather them choose a hash function that isn't susceptible to
length-extension attacks if they do that.

Truncating the v1 tag hadn't come up before, but it might be worth
considering. The goal is to provide a security level of at least 128 bits
where ever we can. Excess is acceptable as long as it's not killing
performance to do so.

​
> ​
> - XChaCha20 has not been formally published before. While it seems an
> “obvious” translation of XSalsa20 to ChaCha20, I’d prefer that to be
> independently specified (e.g. by CFRG) before being the recommended choice.
> XSalsa20 is already published and well known. ​
>
>
Agreed. ​I​ would be much more comfortable culling XChaCha from our draft
and instead referencing an RFC the CFRG approved. Is there any interest in
doing so?

​
> ​
> - The guidelines in section 3.1 are unclear. For instance, they state that
> long nonces (> 128 bits) satisfy “some degree of nonce-misuse resistance”,
> but they do not - at least not in the sense of misuse-resistant
> authenticated encryption (MRAE). They just make randomly-generated nonces
> less likely to collide. The security goals should be clearly defined here.
> ​
>
>
This is an excellent point. I'll work on clarifying the security goals in
the next draft.

​
> ​
> - The guidelines state that public key encryption should be IND-CCA2, but
> public key encryption is not defined in the spec. It’s not clear that
> IND-CCA2 is the right security goal here, vs e.g. public key authenticated
> encryption as in NaCl. ​
>
>
We don't use public-key encryption at all, so you're right that IND-CCA2
isn't an obvious security goal. However, because PKCS1v1.5 padding is used
both for encryption and signatures, and several attacks [2] [3] that can be
combined [4], I felt it was important to outlaw this error-prone
cryptographic mode and anything similar. If that is erroneous, do have a
better definition to suggest in its stead?

---

Rich,

I disagree that AES-CTR + HMAC-SHA2 (encrypt then MAC) is reason enough to
throw anything away.

[1]: http://www.cryptofails.com/post/70059600123/saltstack-rsa-e-d-1
[2]: http://archiv.infsec.ethz.ch/education/fs08/secsem/bleichenbacher98.pdf
[3]: https://www.ietf.org/mail-archive/web/openpgp/current/msg00999.html
[4]: https://robotattack.org

Scott Arciszewski

On Thu, Apr 19, 2018 at 6:03 PM, Neil Madden <[email-masked]>
wrote:

> Firstly, your blog post states that ECDH in JOSE is only defined for NIST
> curves. Actually, RFC 8037 [1] defined X25519/X448 for ECDH in JWE and
> EdDSA for JWS.
>
> I’ll tackle these in reverse order. I find PASETO interesting, but also
> find aspects of the design somewhat confusing:
> ​​
>
> - The basic encryption construction [3] appears (to me at least) to be a
> novel design based on three passes over the message: once to generate a
> pseudorandom nonce in an SIV-like construction (but not actually
> authenticating the message), a second time to encrypt, and then a third
> time to authenticate the cipher text. Is this a well-studied design? What
> security goal is it designed to meet? Why not just use SIV mode?
> ​​
>
> - PASETO still relies on the message to tell it the type of crypto
> algorithms in use: “v1.local” vs “v1.public” vs “v2.local” etc. Isn’t this
> “alg” again, but with a more restricted (and higher-level) set of
> algorithms? I don’t think this is necessary at all - see below for an
> alternative.
> ​​
>
> - There are some odd combinations of security levels defined. For
> instance, v1.local uses untruncated HMAC-SHA384 for authentication (384-bit
> tag), while v2.local uses Poly1305 (128-bit tag) - so v2 is actually
> targeting a lower security level for authentication?
> ​​
>
> - XChaCha20 has not been formally published before. While it seems an
> “obvious” translation of XSalsa20 to ChaCha20, I’d prefer that to be
> independently specified (e.g. by CFRG) before being the recommended choice.
> XSalsa20 is already published and well known.
>
> ​​
> - The guidelines in section 3.1 are unclear. For instance, they state that
> long nonces (> 128 bits) satisfy “some degree of nonce-misuse resistance”,
> but they do not - at least not in the sense of misuse-resistant
> authenticated encryption (MRAE). They just make randomly-generated nonces
> less likely to collide. The security goals should be clearly defined here.
> ​​
>
> - The guidelines state that public key encryption should be IND-CCA2, but
> public key encryption is not defined in the spec. It’s not clear that
> IND-CCA2 is the right security goal here, vs e.g. public key authenticated
> encryption as in NaCl.
>
> So while I appreciate the streamlined design compared to JOSE, there are
> enough non-obvious design decisions here that I am reluctant to immediately
> recommend it as a replacement for JOSE.
>
> But is JOSE fixable instead? I think there is certainly a lot you could do
> to improve it without completely throwing it away and starting again. The
> problem is that old standards never really get thrown away, so we end up
> supporting n+1 standards instead. I think a few basic changes could improve
> the standards considerably:
>
> 1. Deprecating broken/dubious algorithms (like RSA encryption with PKCS#1
> v1.5 padding) and proposing modern and robust replacements (like RFC 8037
> or my own draft for SIV modes [4]).
> 2. Moving the “alg” and “enc” headers out of JWE/JWS and instead into JWK
> so that is the key that determines the algorithm not the message.
> I think these changes would go quite a long way to making JOSE more
> robust. It wouldn’t solve everything (and I have more suggestions for
> another time), but it moves in the right direction. Ultimately I would like
> JWE to gravitate towards authenticated encryption in both symmetric and
> public-key settings, and JWS to concentrate on non-repudiation, but that is
> a larger change.
>
> > 2. ECDAA, whose formal definition eschews the use of deterministic
> nonces [3] and thereby fails to provide the protection of e.g. RFC 6979
> >
> > There is an elegant solution to this trap we've found ourselves in:
> Design an alternative token standard that avoids all of the design deficits
> that plague the incumbent standard, but is still easy to use for at least
> 90% of the JOSE/COSE use-cases. With that in mind, I'd like to present
> PASETO.
> >

---

From: "Salz, Rich" <[email-masked]>
Date: Sat, 28 Apr 2018 16:49:12 +0000

Scott,

If “good and safe” crypto is not 100% in the JOSE ecosystem, you think the solution is a new standard which uses some novel techniques?  Seriously?  To me, a draft which started the process to deprecate the old/bad things seems more effectsive.

---

From: Scott Arciszewski <[email-masked]>
Date: Sat, 28 Apr 2018 12:55:45 -0400

Yes, seriously. Allow me to explain:

Secure cryptography is not backwards compatible with insecure cryptography.
You can't decrypt an RC4-encrypted message by using AES-GCM.

When engineers develop systems that allow for backwards compatibility on
top of incompatible primitives, they're creating room for downgrade attacks
[1] [2].

Making a replacement rather than another iteration doesn't carry that risk.

And keep in mind, my target audience is the sort that has absolutely no
idea how to tell "trivially broken" cryptography from "has a
certificational weakness but is otherwise fine".

[1] https://www.openssl.org/~bodo/ssl-poodle.pdf
[2] https://robotattack.org

Whether or not you agree with my decision (your appetite for risk,
envisioned use case, and target audience might all be totally different
than my own), I don't think it deserves incredulity. (Seriously?)

Scott Arciszewski

On Sat, Apr 28, 2018 at 12:49 PM, Salz, Rich <[email-masked]> wrote:

> Scott,
>
>
>
> If “good and safe” crypto is not 100% in the JOSE ecosystem, you think the
> solution is a new standard which uses some novel techniques?  Seriously?
> To me, a draft which started the process to deprecate the old/bad things
> seems more effectsive.
>

---

From: "Salz, Rich" <[email-masked]>
Date: Sat, 28 Apr 2018 17:40:55 +0000

I mean no offense, but yes, it deserves incredulity.  The way to evolve crypto is to allow for agility (which JSON does), and then migrate off the old onto the new.  Eventually toolkits stop supporting the old.  You can’t decrypt RC4 with AES, but you can use TLS 1.2 between both hosts.

I haven’t followed all of this thread very closely; did you ever explain the “novel construct”?  Has there been any crypto analysis?