W3C home > Mailing lists > Public > public-webcrypto@w3.org > April 2013

Re: Defaults: Getting concrete (round 2)

From: Seetharama Rao Durbha <S.Durbha@cablelabs.com>
Date: Thu, 18 Apr 2013 23:25:04 +0000
To: Ryan Sleevi <sleevi@google.com>, Richard Barnes <rbarnes@bbn.com>
CC: Web Cryptography Working Group <public-webcrypto@w3.org>
Message-ID: <CD95D7D6.B3A6%s.durbha@cablelabs.com>
Looking back at the discussion of this topic (going back to Dec !), it appears to be a philosophical difference  whether the defaults belong in the high-level API or in the low-level API. If these defaults are intended to be covered in a high-level API, then may be it is OK to not have them here.

However, letting the API generate IVs, counters and salts does not sound so dangerous to me. (Though I would not call them 'defaults' - that is appropriate for Algorithms and algorithm parameters). As Richard mentioned sometime back, implementations need to retain them anyway, per operation,  it does not matter who generates them. Actually, it is probably better for security to let the API generate them. Of course, developers can set them if they wish to.

On 4/18/13 4:31 PM, "Ryan Sleevi" <sleevi@google.com<mailto:sleevi@google.com>> wrote:

On Thu, Apr 18, 2013 at 11:05 AM, Richard Barnes <rbarnes@bbn.com<mailto:rbarnes@bbn.com>> wrote:
It would be helpful if you could comment on the merits of this more limited proposal, since it's designed to respond to some of the feedback from earlier rounds.  (And in fact, the last proposal got barely any feedback at all.)


I have repeatedly provided feedback and arguments about why, from an
API perspective, defaults represent something wildly inconsistent with
the API and represent guarantees that cannot be met. I don't think
it's reasonable to ask, when these comments remain unaddressed, that
they be provided every time.

I thought we had put this to rest with the last thread, but continuing
to suggest defaults continues to raise the same issues that have been
highlighted and are fundamentally unaddressible.

As Wan-Teh has pointed out, your proposal already has inconsistencies
in usage between the algorithms.

Further, given how much of the discussion has been shown how defaults
are wrong for the vast majority of algorithms, it seems an entirely
inconsistent API to begin introducing defaults for SOME. It sets an
incredibly difficult and slippery slope about when (and why) defaults
are appropriate from an API perspective, and the only argument being
presented here remains "It'll be more secure".

Your arguments of "It leads to secure code" have been soundly rejected
by a number of people, and yet, if we examine your response to
Wan-Teh, it again seems to be the same argument being presented here -
"IVs are hard to get right"

It seems to me that this proposal provides default values that are compliant with the relevant requirements, with very little burden on implementors.  The only thing that isn't "just generate a random octet string" is CTR, where the implementation might have to keep a message counter per key to ensure uniqueness.

There is concrete benefit here.  Lots of applications, I imagine, are going to want to set an encryption algorithm as a constant and use it for lots of encryptions.  For example:

   var alg = /* algorithm of choice */;
   for (i in foo) {
     let op = window.crypto.encrypt(alg, key, data);
     op.oncomplete = handleCiphertext;

In the current API, this is obviously either impossible (if you don't specify an IV) or broken (if you specify a fixed IV).  To fix this, you need to add "window.crypto.getRandomValues(alg.iv)" before each encrypt() call.  All I'm saying is that we should have encrypt() do the IV population, so that the above works (with alg equal to something like "AES-CBC").

What do you see as the offsetting cost that makes this proposal unacceptable?

It's inconsistent from an API perspective and its justification is
predicated on misguided assumptions.

When you examine the implications of your proposal, the security
benefits for CBC and CFB are going to be extremely limited, given the
need to MAC the data (AND the IV) afterwards, which is as equally
troubling/difficult "to get right".

I don't think your example code is it all representative of a real
world use case because of this, nor do I see how "let iv =
window.crypto.getRandomValues(new ArrayBufferView(16));" to be any
significant burden, compared to the cognitive cost of frequently
having to consider "Is this a default" and "Is there more data in the
result I need to extract"?


On Apr 17, 2013, at 9:17 PM, Ryan Sleevi <sleevi@google.com<mailto:sleevi@google.com>> wrote:

I wouldn't call the feedback lukewarm. I could call it definitively negative.

I still do not support defaults. For all the reasons that have been
discussed and from the public comments.

On Wed, Apr 17, 2013 at 5:43 PM, Richard Barnes <rbarnes@bbn.com<mailto:rbarnes@bbn.com>> wrote:
In light of the few bits of lukewarm feedback on the last concrete proposal on defaults, I would like to make a more focused proposal on the default values that I think are (1) the most obvious, and (2) the most likely to hurt developers.  Namely, IVs for the various AES modes.  Details follow; comments welcome!



Add default values for the "iv" parameters in AesCbcParams, AesCfbParams, AesCtrParams, and AesGcmParams.  During the "parameter normalization" step, these parameters are set by the UA to values meeting the requirements of the relevant NIST specifications.

I. Background: NIST Requirements

The standards for CBC, CFB, and CTR modes is NIST SP800-38A; for GCM, it's SP800-38D.  Here are the relevant requirements for IVs:

For the CBC and CFB modes, the IVs must be unpredictable. In particular, for any given plaintext, it must not be possible to predict the IV that will be associated to the plaintext in advance of the generation of the IV.
[For CTR,]The initial counter blocks, T1, for each message that is encrypted under the given key must be chosen in a manner than ensures the uniqueness of all the counter blocks across all the messages.

The probability that the authenticated encryption function ever will be invoked with the same IV and the same key on two (or more) distinct sets of input data shall be no greater than 2^-32.

The thing to observe here is that the UA can trivially generate IVs that meet these requirements.  For CBC, CFB, and GCM, simply generating pseudo-random value for each call to encrypt() suffices; for CTR, the UA might need to keep a counter with the key to generate message nonces that are guaranteed to unique.  Given that implementing this is so simple and makes it significantly easier to operate securely, we should require the UA to do it.

II. Proposed Revision to Specification

This proposal puts the requirements for UAs to generate values in the IDL describing the parameter dictionaries.  It might be more appropriate to put it somewhere else, e.g., in encrypt().  For brevity, I've only copied in the revised IDL here; changed lines are marked with "XXX".

dictionary AesCbcParams : AlgorithmParameters {
  // The initialization vector. MUST be 16 bytes.
  // If not present, MUST be set on normalization to a random value     XXX
  ArrayBufferView? iv;                                                  XXX

dictionary AesCfbParams : AlgorithmParameters {
  // The initialization vector. MUST be 16 bytes.
  // If not present, MUST be set on normalization to a random value     XXX
  ArrayBufferView? iv;                                                  XXX

dictionary AesCtrParams : AlgorithmParameters {
  // The initial value of the counter block. counter MUST be 16 bytes
  // (the AES block size). The counter bits are the rightmost length
  // bits of the counter block. The rest of the counter block is for
  // the nonce. The counter bits are incremented using the standard
  // incrementing function specified in NIST SP 800-38A Appendix B.1:
  // the counter bits are interpreted as a big-endian integer and
  // incremented by one.
  // If not present, MUST be set on normalization to a UA-selected      XXX
  // value meeting the criteria of NIST SP 800-38A Appendix B.2         XXX
  ArrayBuffer? counter;                                                 XXX
  // The length, in bits, of the rightmost part of the counter block
  // that is incremented.
  [EnforceRange] octet length;

dictionary AesGcmParams : AlgorithmParameters {
  // The initialization vector to use. May be up to 2^56 bytes long.
  // If not present, MUST be set to a random value on normalization,    XXX
  //    of a length chosen by the UA                                    XXX
  ArrayBufferView? iv;                                                  XXX
  // The additional authentication data to include.
  ArrayBufferView? additionalData;
  // The desired length of the authentication tag. May be 0 - 128.
  [EnforceRange] octet? tagLength = 0;
Received on Thursday, 18 April 2013 23:25:33 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:17:16 UTC