- From: Ryan Sleevi <sleevi@google.com>
- Date: Thu, 14 Feb 2013 12:07:26 -0800
- To: Richard Barnes <rbarnes@bbn.com>
- Cc: "public-webcrypto@w3.org Group" <public-webcrypto@w3.org>
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:08:02 UTC