- From: Richard Barnes <rbarnes@bbn.com>
- Date: Thu, 18 Apr 2013 14:05:31 -0400
- To: Ryan Sleevi <sleevi@google.com>
- Cc: Web Cryptography Working Group <public-webcrypto@w3.org>
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.) 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? --Richard On Apr 17, 2013, at 9:17 PM, Ryan Sleevi <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> 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! >> >> Thanks, >> --Richard >> >> >> >> Summary: >> >> 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: >> >> SP800-38A >> """ >> 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. >> """ >> >> SP800-38D >> """ >> 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". >> >> -----BEGIN----- >> 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; >> }; >> -----END----- >> >> >> >
Received on Thursday, 18 April 2013 18:05:59 UTC