- From: Richard Barnes <rbarnes@bbn.com>
- Date: Thu, 14 Feb 2013 15:18:30 -0500
- To: Ryan Sleevi <sleevi@google.com>
- Cc: "public-webcrypto@w3.org Group" <public-webcrypto@w3.org>
Ok, great. Thanks, that does clarify things. I had missed the padding spec in the CBC section. However, it seems rather outside the spirit of the low-level API to include padding in the algorithm. It's necessary in some cases (e.g., RSA signature schemes), but for CBC, it could just as easily be done by the application. --Richard On Feb 14, 2013, at 3:07 PM, Ryan Sleevi <sleevi@google.com> wrote: > On Thu, Feb 14, 2013 at 11:13 AM, Richard Barnes <rbarnes@bbn.com> wrote: >> Suppose I make the following call: >> >> /* my_iv and my_key pre-defined */ >> var my_pt = new Uint8Array(24); >> var my_ct; >> var op = window.crypto.encrypt( >> {name: "AES-CBC", params: {iv: my_iv}}, >> my_key, >> my_pt >> ); >> op.oncomplete = function(e) { >> my_ct = e.target.result; >> } >> >> That is, I've asked the API to encrypt 24 octets -- 1.5 blocks -- of data. However, CBC only operates on whole blocks (unlike CTR, GCM). What should then happen? (Using enc() to represent encryption, and '+' for concatenation) > > Your assumption (that CBC only operates on whole blocks) reflects a > spec ambiguity - one that was raised in Sept and filed as > https://www.w3.org/Bugs/Public/show_bug.cgi?id=18953 > > This was clarified in https://dvcs.w3.org/hg/webcrypto-api/rev/0c723a7d29b3 > >> >> 1) Complete, result = enc(my_pt[0:16]) >> 2) Complete, result = enc(my_pt[0:16]) + my_pt[16:] >> 3) Complete, result = enc(my_pt + padding) >> 4) Error > > As reflected in https://dvcs.w3.org/hg/webcrypto-api/rev/0c723a7d29b3 > , it would be 3 - because the AES-CBC mode is defined to use > PKCS#5/PKCS#7 padding. > > I also note that this is related to you using the 'one-shot' form. > > Consider the following: > > var op = window.crypto.encrypt({name: 'AES-CBC', params: {iv: my_iv}}, my_key); > op.process(new Uint8Array(5)); > op.process(new Uint8Array(19)); > op.process(new Uint8Array(7)); > op.finish(); > > For an implementation that supports incremental encryption, the > expected result would be: > > [op.process(5)] > [op.process(19)] > queue an onProgress, with op.result.byteLength == 16 (that is, it > encrypted the 5 bytes from the first process call and 11 bytes from > the second process call to yield 16 bytes CT) > [op.process(7)] > [op.finish()] > queue an onProgress, with op.result.byteLength == 32 (that is, 8 bytes > remaining from the second process call, the 7 bytes from the third > process call, and 1 byte of padding) > > For an implementation that doesn't support incremental encryption > [op.process(5)] > [op.process(19)] > [op.process(7)] > [op.finish()] > onProgress, with op.result.byteLength == 32 (that is, the combined 31 > bytes, plus one byte of padding) > >> >> Right now, PolyCrypt does (2), because that's what CryptoJS does if you tell it "no padding"; my development branch does (3). I'm pretty sure both of these are wrong, and (1) or (4) should be the outcome. >> >> In terms of the spec, I believe this ambiguity relates to 12.1 / Step 2 / Steps 3/6 (in the branches, respectively). >> >> Thoughts?
Received on Thursday, 14 February 2013 20:19:04 UTC