W3C home > Mailing lists > Public > public-webcrypto@w3.org > October 2012

Re: my revised proposal for ECB (was: Support for ECB - proposal for a decision)

From: Ryan Sleevi <sleevi@google.com>
Date: Fri, 5 Oct 2012 10:14:26 -0700
Message-ID: <CACvaWvbMv0n2eA3WEO3OWRo_J5ApPKmshhvV20xaL22H55fVVw@mail.gmail.com>
To: Zooko Wilcox-OHearn <zooko@leastauthority.com>
Cc: "public-webcrypto@w3.org" <public-webcrypto@w3.org>
On Mon, Oct 1, 2012 at 3:08 PM, Zooko Wilcox-OHearn
<zooko@leastauthority.com> wrote:
> Folks:
>
> I apologize again for being late to today's call. Here is my current
> proposal in light of today's discussion.
>
> 1. We agreed that WebCrypto should specify ECB. (This is a change from
> my earlier position. I agree to specifying ECB because it could be
> more efficient to compute AES on a number of blocks at once, such as
> when implementing an encryption mode of operation.)
>
> 2. I propose that the ECB function take a number of input bytes which
> is an integer multiple of 16, and raise an exception if the input is
> of a different length. That's the standard requirement for ECB.

Is this the input to processData(), or the final result upon calling
.complete()?

In the current processing model, and given that the intent is that
calls to .processData() do not necessarily need to fire a
corresponding event, I would argue that it's highly inappropriate to
have length requirements on .processData(). This applies to any
padding mode - ECB, CBC, OFB, GCM.

If .processData() is called with a length that is not a multiple of
block size (or whatever other requirements exist for the algorithm),
then it should internally buffer until either the conditions are
satisfied (eg: a subsequent set of calls to processData) or until a
signal is received that the user is completed processing (eg:
.complete()).

I think it is important to detach the above semantics from the
discussion of ECB, since they equally apply to other modes - such as
CBC. If a non-blocksize multiple is supplied to .processData(), should
the application:
1) Internally buffer until a multiple of blocksize data is available
or until .complete is called
2) Fail
3) Compute the block by adding the CBC padding and immediately return it

IF we choose 2, we're forcing every application developer to implement
the buffering themselves.
IF we choose 3, we're changing how the API behaves from most common
"Init/Update/Final" APIs behave, which requires a solid justification
as to why to violate expectations as such.

Thus, I think the requirement for a "multiple of 16" only applies in
the context of when discussing at terms of final. And I remain
unconvinced as to the security benefits in practice, since any
developer can (and many developers will) simply random-extend the
buffer to a maximum of size, and then chop off the end.

Again, I do not believe the complexity or simplicity of the
*low-level* API can or should be used as a means to "prevent" bad
crypto, since it's trivial to implement bad crypto atop (as I have
previously demonstrated). Any value to be derived from doing so will,
I strongly believe, be quickly eclipsed by the headaches involved with
arbitrary or capricious complexities for developers who *do* know what
they're doing.

>
> 3. I propose that the API and documentation clearly signal that ECB is
> not an encryption mode. Specifically, I propose that the algorithms
> are grouped like this:
>
> • Public key encryption: RSA-OAEP, RSAES-PKCS1-v1_5
> • Public key digital signature: ECDSA, RSA-PSS, RSASSA-PKCS1-v1_5
> • Key agreement: ECDH, Diffie-Hellman
> • Authenticated encryption: AES-OCB, AES-GCM
> • Unauthenticated encryption: AES-CTR, AES-CBC
> • Message authentication code: HMAC-SHA256
> • Key-derivation functions: HKDF, PBKDF2
> • Primitives: AES-ECB, SHA256

I strongly disagree with the distinction of "SHA" as a Primitive here.
While it's somewhat orthogonal to the ECB proposal, since you've
decided to group all of these things together, I think it's important
for "SHA" to be exposed as a "hash" - so that it can be seamlessly
used with HKDF, PBKDF2, HMAC, and any other SHA-using scheme (eg: PK
signing, PK encryption).

That said, I have reservations about trying to organize the algorithms
into an normative categories, since it goes back to the general
problem of trying to find a hierarchy for all existing/supported
algorithms (see for example what I believe are reasonable points re:
primitives vs. hashing), and in experience, inevitably fails to
consider future algorithms or alternative ways of classifying things.

I would much rather present the list of algorithms as simply that - a
list of algorithms - rather than trying to inject them into
categories. I could live with it, if it was simply for readability,
but the further comments in this e-mail make it very clear that you
feel strongly about this for reasons of security, which I think is a
red herring and a false premise.

>
> And I propose that the documentation of the AES-ECB function say
> something like this:
>
> "NOTE: This function does not, except in special cases, conceal the
> content of the message and cannot, except in special cases, be used
> for encryption. It is included only for the use of cryptographers to
> implement other cryptographic algorithms. For an encryption function,
> please see the functions listed under Authenticated Encryption or
> Unauthenticated Encryption."
>
>
> As a framing note: I care a lot about the security of apps. My work is
> sometimes used by people who risk suffering not just financial loss
> but imprisonment, torture, or murder, if the confidentiality and
> integrity that they need from their apps isn't there. Our work here is
> destined to be used that way, too. People are already using web apps
> such as Crypto.cat to say things that could get them murdered or
> imprisoned if the wrong people overhear, and this trend will increase
> greatly in the coming years.
>
> Older crypto libraries such as Crypto++ ¹, Java ², and .NET ³
> typically included ECB among a list of encryption modes, sometimes
> with a warning note in the documentation. This has been repeatedly
> demonstrated to lead to insecure apps which use ECB mode for
> encryption of secret plaintexts. It is not hypothetical that ECB
> *could* lead to this -- it is established fact that it has done so,
> many times. It is such a common pattern that another instance of it
> was announced while we were having this very conversation: ⁴. In that
> case, a library which included ECB (with warning documentation)
> adjacent to CBC mode and CTR mode led to web sites in which attackers
> could take over the sessions of authenticated users. A different
> library (which I wrote) which excluded ECB mode was not vulnerable to
> that attack.
>
> So it is important to me that the WebCrypto standard doesn't replicate
> these practices which have led to these vulnerabilities. My proposal
> above will, I hope, avoid that.

In my opinion, your proposal fails to do that, but more importantly, I
do not believe our efforts should try to do prevent or solve bad
crypto, as I have repeatedly stated.

I do not consider that "bad software" exists to be a failure of the
API. It is a failure of developers who used a tool in an incorrect
way. That someone wrote a "bad .NET application" does not mean that
the designers of .NET suffered from myopia - it means that some
developer didn't know what they were doing did something bad. Great.
That's the history of computer science. It will continue to be the
history of computer science, for as long as developers are allowed to
write programs that run on general purpose machines.

I'm sure we can get into many ideological discussions about whether
security can be done 'by convention', and what is the true way to get
programmers to do "The Right Thing". I think invoking examples of
"risk of life and limb", while sensational and perhaps attractive to
media outlets, do not belong in a rational and technical discussion
about the merits of the algorithm. I have yet to see such an emotional
appeal made when discussing Content Security Policy or the Web Origin
Model, which are both equally essential to web security, so I think
invoking it here is simply unhelpful for balanced technical
discussions.

Like I said earlier, I support moves to enhance readability and
organization of the spec, but I think we should be clear on why we're
doing it, and I think the framing you gave is problematic, even if it
ends up as a good result, because it means we'll continue to have this
discussion with every algorithm.

Like I mentioned on the call, I would like to eventually see the
possibility of algorithms such as MD5 or 3DES, again on the basis that
this is "just" a low-level API, and there are a number of places where
such algorithms *can* be beneficial (either for legacy reasons or for
acceptable equivalent security propositions). I'm all for including
caveats on those as well - but like I said then as well - I think our
overall goal is to

1) Provide an API that can expose "keys" managed by user agents
without having to give origins *direct* access to the key material
2) Provide an API that allows useful transformations/operations to be
performed on those keys, for any particular value of "useful".

Not to save lives or solve bad crypto.
Received on Friday, 5 October 2012 17:14:55 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Friday, 5 October 2012 17:14:55 GMT