Attempt to describe how the multi-part process() method works, in particular
authorRyan Sleevi <sleevi@google.com>
Mon, 10 Dec 2012 00:40:13 -0800
changeset 17 38a2944310c4
parent 16 b25fc49200d6
child 18 ddc3bad3f496
Attempt to describe how the multi-part process() method works, in particular
how tasks are queued and processed.
spec/Overview-WebCryptoAPI.xml
spec/Overview.html
--- a/spec/Overview-WebCryptoAPI.xml	Mon Dec 10 00:38:10 2012 -0800
+++ b/spec/Overview-WebCryptoAPI.xml	Mon Dec 10 00:40:13 2012 -0800
@@ -821,7 +821,7 @@
           <h3>Structured clone algorithm</h3>
           <p>
             When a user agent is required to obtain a <a href="#dfn-structured-clone">structured clone</a>
-            of a <a href="#dfn-Key">Key</a> object, it must run the following algorithm.
+            of a <a href="#dfn-Key">Key</a> object, it must run the following steps.
           </p>
           <ol>
             <li>
@@ -855,7 +855,6 @@
         <h2>CryptoOperation interface</h2>
         <x:codeblock language="idl">
 interface <dfn id="dfn-CryptoOperation">CryptoOperation</dfn> : <a href="#dfn-EventTarget">EventTarget</a> {
-  void <a href="#dfn-CryptoOperation-method-init">init</a>();
   void <a href="#dfn-CryptoOperation-method-process">process</a>(<a href="#dfn-ArrayBuffer">ArrayBufferView</a> buffer);
   void <a href="#dfn-CryptoOperation-method-finish">finish</a>();
   void <a href="#dfn-CryptoOperation-method-abort">abort</a>();
@@ -866,7 +865,6 @@
 
   [TreatNonCallableasNull] attribute Function? <a href="#dfn-CryptoOperation-onabort">onabort</a>;
   [TreatNonCallableAsNull] attribute Function? <a href="#dfn-CryptoOperation-onerror">onerror</a>;
-  [TreatNonCallableAsNull] attribute Function? <a href="#dfn-CryptoOperation-oninit">oninit</a>;
   [TreatNonCallableAsNull] attribute Function? <a href="#dfn-CryptoOperation-onprogress">onprogress</a>;
   [TreatNonCallableAsNull] attribute Function? <a href="#dfn-CryptoOperation-oncomplete">oncomplete</a>;
 };
@@ -883,66 +881,234 @@
             </li>
           </ul>
         </div>
-        <div id="CryptoOperation-states" class="section">
-          <h3>CryptoOperation states</h3>
+        <div id="CryptoOperation-processing-model" class="section">
+          <h3>Processing Model</h3>
           <p>
-            The <code><a href="#dfn-CryptoOperation">CryptoOperation</a></code> can be in any one of
-            five states. This state is tracked internal to the
-            <code><a href="#dfn-CryptoOperation">CryptoOperation</a></code> and may be used to
-            determine what methods may be called.
+            Every <code>CryptoOperation</code> object must have a <dfn id="dfn-CryptoOperation-list-of-pending-data">list
+            of pending data</dfn>. Each item in the lists represents data that should be transformed by the
+            cryptographic operation. The list functions as a queue that observes first-in, first-out ordering. That is,
+            the order in which items are added shall reflect the order in which items are removed.
           </p>
-          <dl>
-            <dt id="dfn-CryptoOperation-state-empty"><code>"empty"</code></dt>
-            <dd>
-              The <code>CryptoOperation</code> has been constructed, and
-              <code><a href="#dfn-CryptoOperation-method-init">init()</a></code> has not yet been called.
-              This is the default state of a newly constructed <code>CryptoOperation</code> object,
-              until <code><a href="#dfn-CryptoOperation-method-init">init()</a></code> is called.
-            </dd>
-            <dt id="dfn-CryptoOperation-state-initializing"><code>"initializing"</code></dt>
-            <dd>
-              The <code>CryptoOperation</code> is in the midst of performing necessary
-              initialization steps as the result of
-              <code><a href="#dfn-CryptoOperation-method-init">init()</a></code> being called. The
-              <code>CryptoOperation</code> is not yet ready to accept data supplied via
-              <code><a href="#dfn-CryptoOperation-method-process">process()</a></code>.
-            </dd>
-            <dt id="dfn-CryptoOperation-state-processing"><code>"processing"</code></dt>
-            <dd>
-              The <code>CryptoOperation</code> has completed initialization and is ready to process
-              data. More data to be processed may be supplied via
-              <code><a href="#dfn-CryptoOperation-method-process">process()</a></code>, or the
-              operation may be concluded by calling
-              <code><a href="#dfn-CryptoOperation-method-finish">finish()</a></code>.
-            </dd>
-            <dt id="dfn-CryptoOperation-state-completing"><code>"completing"</code></dt>
-            <dd>
-              The <code>CryptoOperation</code> is in the midst of performing the necessary finishing
-              steps to compute the final <a href="#dfn-CryptoOperation-result"><code>result</code></a>,
-              as a result of calling the <a href="#dfn-CryptoOperation-method-finish"><code>finish()</code></a>
-              method. No further data may be provided via the
-              <a href="#dfn-CryptoOperation-method-process"><code>process()</code></a>
-              method.
-            </dd>
-            <dt id="dfn-CryptoOperation-state-complete"><code>"complete"</code></dt>
-            <dd>
-              The <code>CryptoOperation</code> has finished processing data, OR an error occurred
-              during initialization, OR an error occurred during processing, OR the operation was
-              aborted using <code><a href="#dfn-CryptoOperation-method-abort">abort()</a></code>. The
-              <code>CryptoOperation</code> is no longer able to be used to process data.
-            </dd>
-          </dl>
-        </div>
-        <div id="cryptooperation-task-source" class="section">
-          <h3>The CryptoOperation Task Source</h3>
           <p>
-            The <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a> interface enables
-            asynchronous cryptographic processing by firing events. Unless stated otherwise, the
-            <a href="#task-source">task source</a> that is used in this specification is the
-            <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>. This task source is
-            used for events that are asynchronously fired, and for event <a href="#queue-a-task">
-            tasks that are queued</a> for firing.
+            When a CryptoOperation is said to <dfn id="dfn-CryptoOperation-process-data">process data</dfn>, the user
+            agent must execute the following steps:
           </p>
+          <ol>
+            <li>
+              <p>
+                If there are no items in the <a href="dfn-CryptoOperation-list-of-pending-data">list of pending
+                data</a>, the algorithm is complete.
+              </p>
+            </li>
+            <li>
+              <dl class="switch">
+                <dt>
+                  If the underlying cryptographic implementation does not support multi-part cryptographic operations for
+                  the current <a href="#dfn-CryptoOperation-algorithm">algorithm</a>, perform the following steps:
+                </dt>
+                <dd>
+                  <ol>
+                    <li>
+                      <p>
+                        Let <var>bytes</var> be an empty sequence of bytes.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        For each item in the <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>:
+                      </p>
+                      <ol>
+                        <li>
+                          <p>
+                            Let <var>item</var> be the oldest remaining item in the
+                            <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            Remove <var>item</var> from the <a href="#dfn-CryptoOperation-list-of-pending-data">list of
+                            pending data</a>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            Convert <var>item</var> to a sequence of <code>byteLength</code> bytes from the underlying
+                            <code>ArrayBuffer</code>, starting at the <code>byteOffset</code> of the <code>ArrayBufferView</code>,
+                            and append those bytes to <var>bytes</var>
+                          </p>
+                        </li>
+                      </ol>
+                    </li>
+                    <li>
+                      <p>
+                        Perform the underlying cryptographic algorithm, using <var>bytes</var> as the input data.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        If the cryptographic operation fails, proceed to the error steps below:
+                      </p>
+                      <ol>
+                        <li>
+                          <p>
+                            Update the internal state to <code>"error"</code>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            <a href="queue-a-task">Queue a task</a> to
+                            <a href="#fire-a-simple-event">fire a simple event</a> named
+                            <a href="#dfn-CryptoOperation-onerror"><code>onerror</code></a> at the
+                            <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            <a href="#terminate-an-algorithm">Terminate this algorithm</a>.
+                          </p>
+                        </li>
+                      </ol>
+                    </li>
+                    <li>
+                      <p>
+                        Let <var>output</var> be the result of the underlying cryptographic algorithm.
+                      </p>
+                    </li>
+                  </ol>
+                </dd>
+                <dt>
+                  Otherwise, if the underlying cryptographic implementation supports multi-part cryptographic operations
+                  for the current <a href="#dfn-CryptoOperation-algorithm">algorithm</a>, perform the following
+                  algorithm:
+                </dt>
+                <dd>
+                  <ol>
+                    <li>
+                      <p>
+                        Let <var>bytes</var> be an empty sequence of bytes.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        Let <var>item</var> be the oldest remaining item in the
+                        <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        Remove <var>data</var> from the <a href="#dfn-CryptoOperation-list-of-pending-data">list of
+                        pending data</a>.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        Convert <var>item</var> to a sequence of <code>byteLength</code> bytes from the underlying
+                        <code>ArrayBuffer</code>, starting at the <code>byteOffset</code> of the <code>ArrayBufferView</code>,
+                        and append those bytes to <var>bytes</var>
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        A <a href="#dfn-conforming-implementation">conforming user agent</a> <span class="RFC2119">MAY</span>
+                        repeat the preceeding steps as many times as desired, for as long as items remain in the
+                        <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>, provided that the
+                        output of the underlying cryptographic algorithm is indistinguishable from when only a single item is
+                        processed at a time.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        Perform the underlying cryptographic algorithm, using <var>bytes</var> as the input data.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        If the cryptographic operation fails, proceed to the error steps below:
+                      </p>
+                      <ol>
+                        <li>
+                          <p>
+                            Clear the <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            Update the internal state to <code>"error"</code>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            <a href="queue-a-task">Queue a task</a> to
+                            <a href="#fire-a-simple-event">fire a simple event</a> named
+                            <a href="#dfn-CryptoOperation-onerror"><code>onerror</code></a> at the
+                            <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            <a href="#terminate-an-algorithm">Terminate this algorithm</a>.
+                          </p>
+                        </li>
+                      </ol>
+                    </li>
+                    <li>
+                      <p>
+                        Let <var>output</var> be the result of the underlying cryptographic algorithm.
+                      </p>
+                    </li>
+                  </ol>
+                </dd>
+              </dl>
+            </li>
+            <li>
+              <p>
+                Update <a href="#dfn-CryptoOperation-result"><code>result</code></a> with the algorithm-specific
+                result using <var>output</var>.
+              </p>
+              <div class="ednote">
+                <p>
+                  The wording here is presently ambiguous. It is modeled after the [FILE API], which has <code>result</code>
+                  accumulating the output as it becomes available. However, given that support for multi-part input exists,
+                  an interface to support streaming/progressive output has also been requested. How such an interface would
+                  be implemented, if at all, remains TBD.
+                </p>
+              </div>
+            </li>
+            <li>
+              <p>
+                <a href="#fire-a-simple-event">Fire an event</a> named <a href="#dfn-CryptoOperation-onprogress"><code>onprogress</code></a>
+                at the <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>.
+              </p>
+            </li>
+            <li>
+              <p>
+                If the underlying cryptograophic implementation supports multi-part cryptographic operations for the
+                current <a href="#dfn-CryptoOperation-algorithm">algorithm</a>, repeat these steps for each item remaining
+                in the <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>.
+              </p>
+            </li>
+          </ol>
+          <div class="ednote">
+            <ul>
+              <li>
+                <p>
+                  The above algorithm is meant to describe a possible way of supporting multi-part input (also called "streaming"
+                  input, but not to be confused with the [STREAMS API]. The downside to the above algorithm is that it does not
+                  describe a good interface for supporting algorithms that may support multiple multi-part inputs.
+                </p>
+                <p>
+                  An example of such an algorithm would be AES-GCM, which has two sources of input - the encrypted-and-authenticated
+                  data ("ciphertext") and the authenticated data ("additional authenticated data"). A truly multi-part implementation
+                  would allow both the plaintext/ciphertext and the authenticated data to be supplied independently, and in parts,
+                  until <code>finish()</code> was called.
+                </p>
+                <p>
+                  However, at present, several major cryptographic APIs (CDSA, CNG, PKCS#11) do not support this, and so for now, the
+                  details for handling multi-source multi-part data have been omitted.
+                </p>
+              </li>
+            </ul>
+          </div>
         </div>
         <div id="cryptooperation-events" class="section">
           <h3>Event Handler Attributes</h3>
@@ -975,10 +1141,6 @@
                 <td><a href="#dfn-onerror-event">error</a></td>
               </tr>
               <tr>
-                <td><dfn id="dfn-CryptoOperation-oninit">oninit</dfn></td>
-                <td><a href="#dfn-oninit-event">init</a></td>
-              </tr>
-              <tr>
                 <td><dfn id="dfn-CryptoOperation-onprogress">onprogress</dfn></td>
                 <td><a href="#dfn-onprogress-event">progress</a></td>
               </tr>
@@ -1017,16 +1179,9 @@
               <ul>
                 <li>
                   <p>
-                    On getting, if the internal state of the CryptoOperation is the
-                    <a href="#dfn-CryptoOperation-state-empty"><code>"empty"</code></a> state,
-                    then the <code>result</code> attribute <span class="RFC2119">MUST</span>
-                    return <code>null</code>.
-                  </p>
-                </li>
-                <li>
-                  <p>
                     On getting, if an error in performing the operation has occurred, then the
-                    <code>result</code> attribute <span class="RFC2119">MUST</span> return <code>null</code>.
+                    <code>result</code> attribute <span class="RFC2119">MUST</span> return
+                    <code>null</code>.
                   </p>
                 </li>
               </ul>
@@ -1034,108 +1189,47 @@
           </dl>
         </div>
         <div id="CryptoOperation-methods" class="section">
-          <h3>Methods and Parameters</h3>
-          <div id="CryptoOperation-method-init" class="section">
-            <h4>The <dfn id="dfn-CryptoOperation-method-init"><code>init</code></dfn> method</h4>
+          <h3>Methods</h3>
+          <div id="CryptoOperation-method-process" class="section">
+            <h4><dfn id="dfn-CryptoOperation-method-process"><code>process(ArrayBufferView data)</code></dfn></h4>
             <p>
-              When <a href="#dfn-CryptoOperation-method-init"><code>init</code></a> method is called,
-              the user agent must run the steps below.
+              When the <code>process(ArrayBufferView data)</code> method is called, the user agent must run
+              the following steps:
             </p>
             <ol>
               <li>
-                If the internal <a href="#CryptoOperation-states">state</a> is not in the
-                <code><a href="#dfn-CryptoOperation-state-empty">"empty"</a></code> state,
-                throw an <code>InvalidStateError</code> exception [<a href="#DOM4">DOM4</a>] and
-                <dfn id="terminate-the-algorithm">terminate the algorithm</dfn>.
-              </li>
-              <li>
-                Set the internal <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-initializing">"initializing"</a></code>.
-              </li>
-              <li>
-                Return from the <code>init()</code> method, but continue processing the steps in this
-                algorithm.
+                <p>
+                  If the internal state is in the <code>"error"</code> state, throw an
+                  <code>InvalidStateError</code> exception and abort these steps.
+                </p>
               </li>
               <li>
-                If an error occurs during initialization, set the internal
-                <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-complete">complete</a></code> and set
-                <code><a href="#dfn-CryptoOperation-result">result</a></code> to null. Proceed to the
-                error steps below.
-                <ol>
-                  <li>
-                    Fire an event called <code><a href="#dfn-onerror-event">error</a></code>.
-                  </li>
-                  <li>
-                    Terminate this algorithm.
-                  </li>
-                </ol>
+                <p>
+                  Let <var>data</var> be the data to be processed.
+                </p>
               </li>
               <li>
-                When the <code>CryptoOperation</code> is fully initialized, set the
-                <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-processing">processing</a></code>.
+                <p>
+                  Add <var>data</var> to the <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>.
+                </p>
               </li>
               <li>
-                Fire an event called <code><a href="#dfn-oninit-event">init</a></code>.
-              </li>
-              <li>
-                Terminate this algorithm.
+                <p>
+                  If the underlying cryptographic implementation for the specified
+                  <a href="#dfn-CryptoOperation-algorithm">algorithm</a> supports multi-part cryptographic operations,
+                  asynchrously <a href="#dfn-CryptoOperation-process-data">process data</a>, allowing the task that
+                  invoked this algorithm to continue.
+                </p>
+                <div class="ednote">
+                  <p>
+                    Warning: The text here is currently ambiguous in terms of defining how the <code>event loop</code>
+                    processes events; in particular, it leaves under-specified how the <a href="#dfn-CryptoOperation-method-abort">
+                    <code>abort()</code></a> method should be handled when data is being processed.
+                  </p>
+                </div>
               </li>
             </ol>
           </div>
-          <div id="CryptoOperation-method-process" class="section">
-            <h4>The <dfn id="dfn-CryptoOperation-method-process"><code>process(ArrayBufferView buffer)</code></dfn> method</h4>
-            <p>
-              When <a href="#dfn-CryptoOperation-method-process"><code>process(ArrayBufferView buffer)</code></a>
-              method is called, the user agent must run the steps below.
-            </p>
-            <ol>
-              <li>
-                If the internal <a href="#CryptoOperation-states">state</a> is not in the
-                <code><a href="#dfn-CryptoOperation-state-processing">"processing"</a></code> state,
-                throw an <code>InvalidStateError</code> exception [<a href="#DOM4">DOM4</a>] and
-                <dfn id="terminate-the-algorithm">terminate the algorithm</dfn>.
-              </li>
-              <li>
-                Return from the <code>process()</code> method, but continue processing the steps in
-                this algorithm.
-              </li>
-              <li>
-                If an error occurs during processing, set the internal
-                <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-complete">complete</a></code> and set
-                <code><a href="#dfn-CryptoOperation-result">result</a></code> to null. Proceed to the
-                error steps below.
-                <ol>
-                  <li>
-                    Fire an event called <code><a href="#dfn-onerror-event">error</a></code>.
-                  </li>
-                  <li>
-                    Terminate this algorithm.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Perform the algorithm-specific processing.
-              </li>
-              <li>
-                If processing resulted in <code>output</code>, perform the following steps.
-                <ol>
-                  <li>
-                    Queue a task to update <code><a href="#dfn-CryptoOperation-result">result</a></code>
-                    with the <code>output</code>
-                  </li>
-                  <li>
-                    Fire an event called <code><a href="#dfn-onprogress-event">progress</a></code>.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Terminate this algorithm.
-              </li>
-            </ol>          
-          </div>
           <div id="CryptoOperation-method-finish" class="section">
             <h4>The <dfn id="dfn-CryptoOperation-method-finish"><code>finish()</code></dfn> method</h4>
             <p>
@@ -1144,56 +1238,32 @@
             </p>
             <ol>
               <li>
-                If the internal <a href="#CryptoOperation-states">state</a> is not in the
-                <code><a href="#dfn-CryptoOperation-state-processing">"processing"</a></code> state,
-                throw an <code>InvalidStateError</code> exception [<a href="#DOM4">DOM4</a>] and
-                <dfn id="terminate-the-algorithm">terminate the algorithm</dfn>.
-              </li>
-              <li>
-                Set the internal <a href="#CryptoOperation-states">state</a> to
-                <a href="#dfn-CryptoOperation-state-completing"><code>completing</code></a>.
-              </li>
-              <li>
-                Return from the <code>finish()</code> method, but continue processing the steps in
-                this algorithm.
+                <p>
+                  If the internal state is in the <code>"error"</code> state, throw an
+                  <code>InvalidStateError</code> exception and abort these steps.
+                </p>
               </li>
               <li>
-                If an error occurs during processing, set the internal
-                <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-complete">complete</a></code> and set
-                <code><a href="#dfn-CryptoOperation-result">result</a></code> to null. Proceed to the
-                error steps below.
-                <ol>
-                  <li>
-                    Fire an event called <code><a href="#dfn-onerror-event">error</a></code>.
-                  </li>
-                  <li>
-                    Terminate this algorithm.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Perform the algorithm-specific processing.
+                <p>
+                  Set the internal state to <code>"complete"</code>.
+                </p>
               </li>
               <li>
-                Let <var>output</var> be the result of the algorithm-specific processing.
-              </li>
-              <li>
-                Queue a task to update <code><a href="#dfn-CryptoOperation-result">result</a></code>
-                with the <var>output</var>
+                <p>
+                  If the underlying cryptographic implementation for the specified
+                  <a href="#dfn-CryptoOperation-algorithm">algorithm</a> does not support multi-part cryptographic
+                  operations, asynchronously <a href="#dfn-CryptoOperation-process-data">process data</a>, allowing the task
+                  that invoked this algorithm to continue.
+                </p>
               </li>
               <li>
-                Fire an event called <code><a href="#dfn-onprogress-event">progress</a></code>.
-              </li>
-              <li>
-                Set the internal <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-complete">complete</a></code>.
-              </li>
-              <li>
-                Fire an event called <code><a href="#dfn-oncomplete-event">complete</a></code>.
-              </li>
-              <li>
-                Terminate this algorithm.
+                <p>
+                  Once all items in the <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a> have
+                  been <a href="#dfn-CryptoOperation-process-data">processed</a>, <a href="#queue-a-task">queue a task</a>
+                  to <a href="#fire-a-simple-event">fire an event</a> called
+                  <a href="#dfn-CryptoOperation-oncomplete"><code>oncomplete</code></a> at the
+                  <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>.
+                </p>
               </li>
             </ol>
           </div>
@@ -1205,76 +1275,13 @@
             </p>
             <ol>
               <li>
-                If the internal <a href="#CryptoOperation-states">state</a> is either
-                <a href="#dfn-CryptoOperation-state-empty"><code>"empty"</code></a> or
-                <a href="#dfn-CryptoOperation-state-complete"><code>"complete"</code></a>, set
-                <a href="#dfn-CryptoOperation-result"><code>result</code></a> to <code>null</code>
-                and terminate this overall set of steps without doing anything else.
-              </li>
-              <li>
                 <p>
-                  If the internal <a href="#CryptoOperation-states">state</a> is
-                  <a href="#dfn-CryptoOperation-state-initializing"><code>"initializing"</code></a>,
-                  then perform the following steps:
+                  If the internal state is in the <code>"error"</code> state, throw an
+                  <code>InvalidStateError</code> exception and abort these steps.
                 </p>
-                <ol>
-                  <li>
-                    Set the internal <a href="#CryptoOperation-states">state</a> to
-                    <a href="#dfn-CryptoOperation-state-complete"><code>"complete"</code></a>.
-                  </li>
-                  <li>
-                    Set <a href="#dfn-CryptoOperation-result"><code>result</code></a> to
-                    <code>null</code>.
-                  </li>
-                  <li>
-                    <a href="#terminate-the-algorithm">Terminate the algorithm</a> for the
-                    <a href="#dfn-CryptoOperation-method-init"><code>init()</code></a> method.
-                  </li>
-                </ol>
               </li>
               <li>
-                <p>
-                  If the internal <a href="#CryptoOperation-states">state</a> is
-                  <a href="#dfn-CryptoOperation-state-processing"><code>"processing"</code></a>,
-                  then perform the following steps:
-                </p>
-                <ol>
-                  <li>
-                    Set the internal <a href="#CryptoOperation-states">state</a> to
-                    <a href="#dfn-CryptoOperation-state-complete"><code>"complete"</code></a>.
-                  </li>
-                  <li>
-                    Set <a href="#dfn-CryptoOperation-result"><code>result</code></a> to
-                    <code>null</code>.
-                  </li>
-                  <li>
-                    <a href="#terminate-the-algorithm">Terminate the algorithm</a> for the
-                    <a href="#dfn-CryptoOperation-method-process"><code>process()</code></a>
-                    method.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                <p>
-                  If the internal <a href="#CryptoOperation-states">state</a> is
-                  <a href="#dfn-CryptoOperation-state-completing"><code>"completing"</code></a>,
-                  then perform the following steps:
-                </p>
-                <ol>
-                  <li>
-                    Set the internal <a href="#CryptoOperation-states">state</a> to
-                    <a href="#dfn-CryptoOperation-state-complete"><code>"complete"</code></a>.
-                  </li>
-                  <li>
-                    Set <a href="#dfn-CryptoOperation-result"><code>result</code></a> to
-                    <code>null</code>.
-                  </li>
-                  <li>
-                    <a href="#terminate-the-algorithm">Terminate the algorithm</a> for the
-                    <a href="#dfn-CryptoOperation-method-finish"><code>finish()</code></a>
-                    method.
-                  </li>
-                </ol>
+                <p>Abort <a href="#dfn-CryptoOperation-process-data">processing data</a>.</p>
               </li>
               <li>
                 If there are any tasks from the object's
@@ -1285,6 +1292,11 @@
                 Fire an event called <a href="#dfn-onabort-event"><code>abort</code></a>.
               </li>
             </ol>
+            <div class="ednote">
+              <p>
+                The above algorithm is underspecified.
+              </p>
+            </div>
           </div>
         </div>
       </div>
--- a/spec/Overview.html	Mon Dec 10 00:38:10 2012 -0800
+++ b/spec/Overview.html	Mon Dec 10 00:40:13 2012 -0800
@@ -49,7 +49,7 @@
 communications.
       </p>
   
-      <div class="ednote"><div class="ednoteHeader">Editorial note</div><p>There are 11 further editorial notes in the document.</p></div>
+      <div class="ednote"><div class="ednoteHeader">Editorial note</div><p>There are 15 further editorial notes in the document.</p></div>
     </div>
 
     <div class="section">
@@ -145,7 +145,7 @@
 
     <div id="toc">
       <h2>Table of Contents</h2>
-      <div class="toc"><ul><li><a href="#introduction">1. Introduction</a></li><li><a href="#use-cases">2. Use Cases</a><ul><li><a href="#multifactor-authentication">2.1. Multi-factor Authentication</a></li><li><a href="#protected-document">2.2. Protected Document Exchange</a></li><li><a href="#cloud-storage">2.3. Cloud Storage</a></li><li><a href="#document-signing">2.4. Document Signing</a></li><li><a href="#data-integrity-protection">2.5. Data Integrity Protection</a></li><li><a href="#secure-messaging">2.6. Secure Messaging</a></li><li><a href="#jose">2.7. Javascript Object Signing and Encryption (JOSE)</a></li></ul></li><li><a href="#conformance">3. Conformance</a></li><li><a href="#scope">4. Scope</a><ul><li><a href="#scope-abstraction">4.1. Level of abstraction</a></li><li><a href="#scope-algorithms">4.2. Cryptographic algorithms</a></li><li><a href="#scope-operations">4.3. Operations</a></li><li><a href="#scope-out-of-scope">4.4. Out of scope</a></li></ul></li><li><a href="#security">5. Security considerations</a><ul><li><a href="#security-implementers">5.1. Security considerations for implementers</a></li><li><a href="#security-developers">5.2. Security considerations for developers</a></li></ul></li><li><a href="#privacy">6. Privacy considerations</a></li><li><a href="#dependencies">7. Dependencies</a></li><li><a href="#terminology">8. Terminology</a></li><li><a href="#RandomSource-interface">9. RandomSource interface</a><ul><li><a href="#RandomSource-description">9.1. Description</a></li><li><a href="#RandomSource-interface-methods">9.2. Methods and Parameters</a><ul><li><a href="#RandomSource-method-getRandomValues">9.2.1. The getRandomValues method</a></li></ul></li></ul></li><li><a href="#algorithm-dictionary">10. Algorithm dictionary</a><ul><li><a href="#algorithm-dictionary-members">10.1. Algorithm Dictionary Members</a></li></ul></li><li><a href="#key-interface">11. Key interface</a><ul><li><a href="#key-interface-description">11.1. Description</a></li><li><a href="#key-interface-members">11.2. Key interface members</a></li><li><a href="#key-interface-clone">11.3. Structured clone algorithm</a></li></ul></li><li><a href="#cryptooperation-interface">12. CryptoOperation interface</a><ul><li><a href="#CryptoOperation-states">12.1. CryptoOperation states</a></li><li><a href="#cryptooperation-task-source">12.2. The CryptoOperation Task Source</a></li><li><a href="#cryptooperation-events">12.3. Event Handler Attributes</a></li><li><a href="#CryptoOperation-attributes">12.4. Attributes</a></li><li><a href="#CryptoOperation-methods">12.5. Methods and Parameters</a><ul><li><a href="#CryptoOperation-method-init">12.5.1. The init method</a></li><li><a href="#CryptoOperation-method-process">12.5.2. The process(ArrayBufferView buffer) method</a></li><li><a href="#CryptoOperation-method-finish">12.5.3. The finish() method</a></li><li><a href="#CryptoOperation-method-abort">12.5.4. The abort() method</a></li></ul></li></ul></li><li><a href="#KeyOperation-interface">13. KeyOperation interface</a></li><li><a href="#KeyGenerator-interface">14. KeyGenerator interface</a></li><li><a href="#KeyDeriver-interface">15. KeyDeriver interface</a></li><li><a href="#KeyImporter-interface">16. KeyImporter interface</a></li><li><a href="#KeyExporter-interface">17. KeyExporter interface</a></li><li><a href="#crypto-interface">18. Crypto interface</a><ul><li><a href="#crypto-interface-methods">18.1. Methods and Parameters</a><ul><li><a href="#Crypto-method-createEncrypter">18.1.1. The createEncrypter method</a></li><li><a href="#Crypto-method-createDecrypter">18.1.2. The createDecrypter method</a></li><li><a href="#Crypto-method-createSigner">18.1.3. The createSigner method</a></li><li><a href="#Crypto-method-createVerifier">18.1.4. The createVerifier method</a></li><li><a href="#Crypto-method-createDigester">18.1.5. The createDigester method</a></li><li><a href="#Crypto-method-createKeyGenerator">18.1.6. The createKeyGenerator method</a></li><li><a href="#Crypto-method-createKeyDeriver">18.1.7. The createKeyDeriver method</a></li><li><a href="#Crypto-method-createKeyImporter">18.1.8. The createKeyImporter method</a></li><li><a href="#Crypto-method-createKeyExporter">18.1.9. The createKeyExporter method</a></li></ul></li></ul></li><li><a href="#WorkerCrypto-interface">19. WorkerCrypto interface</a><ul><li><a href="#WorkerCrypto-description">19.1. Description</a></li></ul></li><li><a href="#big-integer">20. BigInteger</a></li><li><a href="#keypair">21. KeyPair</a></li><li><a href="#key-discovery">22. Key Discovery</a></li><li><a href="#algorithms">23. Algorithms</a><ul><li><a href="#recommended-algorithms">23.1. Recommended algorithms</a></li><li><a href="#defining-an-algorithm">23.2. Defining an algorithm</a><ul><li><a href="#recognized-algorithm-name">23.2.1. Recognized algorithm name</a></li><li><a href="#supported-operations">23.2.2. Supported operations</a></li><li><a href="#algorithm-specific-params">23.2.3. Algorithm-specific parameters</a></li><li><a href="#algorithm-result">23.2.4. Algorithm results</a></li><li><a href="#algorithm-alias">23.2.5. Algorithm aliases</a></li></ul></li><li><a href="#rsaes-pkcs1">23.3. RSAES-PKCS1-v1_5</a><ul><li><a href="#rsaes-pkcs1-description">23.3.1. Description</a></li><li><a href="#rsaes-pkcs1-registration">23.3.2. Registration</a></li><li><a href="#RsaKeyGenParams-dictionary">23.3.3. RsaKeyGenParams dictionary</a></li><li><a href="#rsaes-pkcs1-operations">23.3.4. Operations</a></li></ul></li><li><a href="#rsassa-pkcs1">23.4. RSASSA-PKCS1-v1_5</a><ul><li><a href="#rsassa-pkcs1-description">23.4.1. Description</a></li><li><a href="#rsassa-pkcs1-registration">23.4.2. Registration</a></li><li><a href="#RsaSsaParams-dictionary">23.4.3. RsaSsaParams dictionary</a></li><li><a href="#rsassa-pkcs1-operations">23.4.4. Operations</a></li></ul></li><li><a href="#rsa-pss">23.5. RSA-PSS</a><ul><li><a href="#rsa-pss-description">23.5.1. Description</a></li><li><a href="#rsa-pss-registration">23.5.2. Registration</a></li><li><a href="#rsa-pss-params">23.5.3. RsaPssParams dictionary</a></li><li><a href="#rsa-pss-operations">23.5.4. Operations</a></li></ul></li><li><a href="#rsa-oaep">23.6. RSA-OAEP</a><ul><li><a href="#rsa-oaep-description">23.6.1. Description</a></li><li><a href="#rsa-oaep-registration">23.6.2. Registration</a></li><li><a href="#rsa-oaep-params">23.6.3. RsaOaepParams dictionary</a></li><li><a href="#rsa-oaep-operations">23.6.4. Operations</a></li></ul></li><li><a href="#ecdsa">23.7. ECDSA</a><ul><li><a href="#ecdsa-description">23.7.1. Description</a></li><li><a href="#ecdsa-registration">23.7.2. Registration</a></li><li><a href="#EcdsaParams-dictionary">23.7.3. EcdsaParams dictionary</a></li><li><a href="#EcKeyGenParams-dictionary">23.7.4. EcKeyGenParams dictionary</a></li><li><a href="#ecdsa-operations">23.7.5. Operations</a></li></ul></li><li><a href="#ecdh">23.8. ECDH</a><ul><li><a href="#ecdh-description">23.8.1. Description</a></li><li><a href="#ecdh-registration">23.8.2. Registration</a></li><li><a href="#dh-EcdhKeyDeriveParams">23.8.3. EcdhKeyDeriveParams dictionary</a></li><li><a href="#ecdh-operations">23.8.4. Operations</a></li></ul></li><li><a href="#aes-ctr">23.9. AES-CTR</a><ul><li><a href="#aes-ctr-description">23.9.1. Description</a></li><li><a href="#aes-ctr-registration">23.9.2. Registration</a></li><li><a href="#aes-ctr-params">23.9.3. AesCtrParams dictionary</a></li><li><a href="#aes-keygen-params">23.9.4. AesKeyGenParams dictionary</a></li><li><a href="#aes-ctr-operations">23.9.5. Operations</a></li></ul></li><li><a href="#aes-cbc">23.10. AES-CBC</a><ul><li><a href="#aes-cbc-description">23.10.1. Description</a></li><li><a href="#aes-cbc-registration">23.10.2. Registration</a></li><li><a href="#aes-cbc-params">23.10.3. AesCbcParams dictionary</a></li><li><a href="#aes-cbc-operations">23.10.4. Operations</a></li></ul></li><li><a href="#aes-gcm">23.11. AES-GCM</a><ul><li><a href="#aes-gcm-description">23.11.1. Description</a></li><li><a href="#aes-gcm-registration">23.11.2. Registration</a></li><li><a href="#aes-gcm-params">23.11.3. AesGcmParams dictionary</a></li><li><a href="#aes-gcm-operations">23.11.4. Operations</a></li></ul></li><li><a href="#hmac">23.12. HMAC</a><ul><li><a href="#hmac-description">23.12.1. Description</a></li><li><a href="#hmac-registration">23.12.2. Registration</a></li><li><a href="#hmac-params">23.12.3. HmacParams dictionary</a></li><li><a href="#hmac-operations">23.12.4. Operations</a></li></ul></li><li><a href="#dh">23.13. Diffie-Hellman</a><ul><li><a href="#dh-description">23.13.1. Description</a></li><li><a href="#dh-registration">23.13.2. Registration</a></li><li><a href="#dh-DhKeyGenParams">23.13.3. DhKeyGenParams dictionary</a></li><li><a href="#dh-DhKeyDeriveParams">23.13.4. DhKeyDeriveParams dictionary</a></li><li><a href="#dh-operations">23.13.5. Operations</a></li></ul></li><li><a href="#sha">23.14. SHA</a><ul><li><a href="#sha-description">23.14.1. Description</a></li><li><a href="#sha-registration">23.14.2. Registration</a></li><li><a href="#sha-operations">23.14.3. Operations</a></li></ul></li><li><a href="#concatkdf">23.15. Concat KDF</a><ul><li><a href="#concatkdf-description">23.15.1. Description</a></li><li><a href="#concatkdf-registration">23.15.2. Registration</a></li><li><a href="#concat-params">23.15.3. ConcatParams dictionary</a></li><li><a href="#concat-operations">23.15.4. Operations</a></li></ul></li><li><a href="#pbkdf2">23.16. PBKDF2</a><ul><li><a href="#pbkdf2-description">23.16.1. Description</a></li><li><a href="#pbkdf2-registration">23.16.2. Registration</a></li><li><a href="#pbkdf2-params">23.16.3. Pbkdf2Params dictionary</a></li><li><a href="#pbkdf2-operations">23.16.4. Operations</a></li></ul></li></ul></li><li><a href="#algorithm-normalizing-rules">24. Algorithm normalizing rules</a></li><li><a href="#examples-section">25. JavaScript Example Code</a><ul><li><a href="#examples-signing">25.1. Generate a signing key pair, sign some data</a></li><li><a href="#examples-symmetric-encryption">25.2. Symmetric Encryption</a></li></ul></li><li><a href="#acknowledgements-section">26. Acknowledgements</a></li><li><a href="#references">27. References</a><ul><li><a href="#normative-references">27.1. Normative References</a></li><li><a href="#informative-references">27.2. Informative References</a></li></ul></li></ul></div>
+      <div class="toc"><ul><li><a href="#introduction">1. Introduction</a></li><li><a href="#use-cases">2. Use Cases</a><ul><li><a href="#multifactor-authentication">2.1. Multi-factor Authentication</a></li><li><a href="#protected-document">2.2. Protected Document Exchange</a></li><li><a href="#cloud-storage">2.3. Cloud Storage</a></li><li><a href="#document-signing">2.4. Document Signing</a></li><li><a href="#data-integrity-protection">2.5. Data Integrity Protection</a></li><li><a href="#secure-messaging">2.6. Secure Messaging</a></li><li><a href="#jose">2.7. Javascript Object Signing and Encryption (JOSE)</a></li></ul></li><li><a href="#conformance">3. Conformance</a></li><li><a href="#scope">4. Scope</a><ul><li><a href="#scope-abstraction">4.1. Level of abstraction</a></li><li><a href="#scope-algorithms">4.2. Cryptographic algorithms</a></li><li><a href="#scope-operations">4.3. Operations</a></li><li><a href="#scope-out-of-scope">4.4. Out of scope</a></li></ul></li><li><a href="#security">5. Security considerations</a><ul><li><a href="#security-implementers">5.1. Security considerations for implementers</a></li><li><a href="#security-developers">5.2. Security considerations for developers</a></li></ul></li><li><a href="#privacy">6. Privacy considerations</a></li><li><a href="#dependencies">7. Dependencies</a></li><li><a href="#terminology">8. Terminology</a></li><li><a href="#RandomSource-interface">9. RandomSource interface</a><ul><li><a href="#RandomSource-description">9.1. Description</a></li><li><a href="#RandomSource-interface-methods">9.2. Methods and Parameters</a><ul><li><a href="#RandomSource-method-getRandomValues">9.2.1. The getRandomValues method</a></li></ul></li></ul></li><li><a href="#algorithm-dictionary">10. Algorithm dictionary</a><ul><li><a href="#algorithm-dictionary-members">10.1. Algorithm Dictionary Members</a></li></ul></li><li><a href="#key-interface">11. Key interface</a><ul><li><a href="#key-interface-description">11.1. Description</a></li><li><a href="#key-interface-members">11.2. Key interface members</a></li><li><a href="#key-interface-clone">11.3. Structured clone algorithm</a></li></ul></li><li><a href="#cryptooperation-interface">12. CryptoOperation interface</a><ul><li><a href="#CryptoOperation-processing-model">12.1. Processing Model</a></li><li><a href="#cryptooperation-events">12.2. Event Handler Attributes</a></li><li><a href="#CryptoOperation-attributes">12.3. Attributes</a></li><li><a href="#CryptoOperation-methods">12.4. Methods</a><ul><li><a href="#CryptoOperation-method-process">12.4.1. process(ArrayBufferView data)</a></li><li><a href="#CryptoOperation-method-finish">12.4.2. The finish() method</a></li><li><a href="#CryptoOperation-method-abort">12.4.3. The abort() method</a></li></ul></li></ul></li><li><a href="#KeyOperation-interface">13. KeyOperation interface</a></li><li><a href="#KeyGenerator-interface">14. KeyGenerator interface</a></li><li><a href="#KeyDeriver-interface">15. KeyDeriver interface</a></li><li><a href="#KeyImporter-interface">16. KeyImporter interface</a></li><li><a href="#KeyExporter-interface">17. KeyExporter interface</a></li><li><a href="#crypto-interface">18. Crypto interface</a><ul><li><a href="#crypto-interface-methods">18.1. Methods and Parameters</a><ul><li><a href="#Crypto-method-createEncrypter">18.1.1. The createEncrypter method</a></li><li><a href="#Crypto-method-createDecrypter">18.1.2. The createDecrypter method</a></li><li><a href="#Crypto-method-createSigner">18.1.3. The createSigner method</a></li><li><a href="#Crypto-method-createVerifier">18.1.4. The createVerifier method</a></li><li><a href="#Crypto-method-createDigester">18.1.5. The createDigester method</a></li><li><a href="#Crypto-method-createKeyGenerator">18.1.6. The createKeyGenerator method</a></li><li><a href="#Crypto-method-createKeyDeriver">18.1.7. The createKeyDeriver method</a></li><li><a href="#Crypto-method-createKeyImporter">18.1.8. The createKeyImporter method</a></li><li><a href="#Crypto-method-createKeyExporter">18.1.9. The createKeyExporter method</a></li></ul></li></ul></li><li><a href="#WorkerCrypto-interface">19. WorkerCrypto interface</a><ul><li><a href="#WorkerCrypto-description">19.1. Description</a></li></ul></li><li><a href="#big-integer">20. BigInteger</a></li><li><a href="#keypair">21. KeyPair</a></li><li><a href="#key-discovery">22. Key Discovery</a></li><li><a href="#algorithms">23. Algorithms</a><ul><li><a href="#recommended-algorithms">23.1. Recommended algorithms</a></li><li><a href="#defining-an-algorithm">23.2. Defining an algorithm</a><ul><li><a href="#recognized-algorithm-name">23.2.1. Recognized algorithm name</a></li><li><a href="#supported-operations">23.2.2. Supported operations</a></li><li><a href="#algorithm-specific-params">23.2.3. Algorithm-specific parameters</a></li><li><a href="#algorithm-result">23.2.4. Algorithm results</a></li><li><a href="#algorithm-alias">23.2.5. Algorithm aliases</a></li></ul></li><li><a href="#rsaes-pkcs1">23.3. RSAES-PKCS1-v1_5</a><ul><li><a href="#rsaes-pkcs1-description">23.3.1. Description</a></li><li><a href="#rsaes-pkcs1-registration">23.3.2. Registration</a></li><li><a href="#RsaKeyGenParams-dictionary">23.3.3. RsaKeyGenParams dictionary</a></li><li><a href="#rsaes-pkcs1-operations">23.3.4. Operations</a></li></ul></li><li><a href="#rsassa-pkcs1">23.4. RSASSA-PKCS1-v1_5</a><ul><li><a href="#rsassa-pkcs1-description">23.4.1. Description</a></li><li><a href="#rsassa-pkcs1-registration">23.4.2. Registration</a></li><li><a href="#RsaSsaParams-dictionary">23.4.3. RsaSsaParams dictionary</a></li><li><a href="#rsassa-pkcs1-operations">23.4.4. Operations</a></li></ul></li><li><a href="#rsa-pss">23.5. RSA-PSS</a><ul><li><a href="#rsa-pss-description">23.5.1. Description</a></li><li><a href="#rsa-pss-registration">23.5.2. Registration</a></li><li><a href="#rsa-pss-params">23.5.3. RsaPssParams dictionary</a></li><li><a href="#rsa-pss-operations">23.5.4. Operations</a></li></ul></li><li><a href="#rsa-oaep">23.6. RSA-OAEP</a><ul><li><a href="#rsa-oaep-description">23.6.1. Description</a></li><li><a href="#rsa-oaep-registration">23.6.2. Registration</a></li><li><a href="#rsa-oaep-params">23.6.3. RsaOaepParams dictionary</a></li><li><a href="#rsa-oaep-operations">23.6.4. Operations</a></li></ul></li><li><a href="#ecdsa">23.7. ECDSA</a><ul><li><a href="#ecdsa-description">23.7.1. Description</a></li><li><a href="#ecdsa-registration">23.7.2. Registration</a></li><li><a href="#EcdsaParams-dictionary">23.7.3. EcdsaParams dictionary</a></li><li><a href="#EcKeyGenParams-dictionary">23.7.4. EcKeyGenParams dictionary</a></li><li><a href="#ecdsa-operations">23.7.5. Operations</a></li></ul></li><li><a href="#ecdh">23.8. ECDH</a><ul><li><a href="#ecdh-description">23.8.1. Description</a></li><li><a href="#ecdh-registration">23.8.2. Registration</a></li><li><a href="#dh-EcdhKeyDeriveParams">23.8.3. EcdhKeyDeriveParams dictionary</a></li><li><a href="#ecdh-operations">23.8.4. Operations</a></li></ul></li><li><a href="#aes-ctr">23.9. AES-CTR</a><ul><li><a href="#aes-ctr-description">23.9.1. Description</a></li><li><a href="#aes-ctr-registration">23.9.2. Registration</a></li><li><a href="#aes-ctr-params">23.9.3. AesCtrParams dictionary</a></li><li><a href="#aes-keygen-params">23.9.4. AesKeyGenParams dictionary</a></li><li><a href="#aes-ctr-operations">23.9.5. Operations</a></li></ul></li><li><a href="#aes-cbc">23.10. AES-CBC</a><ul><li><a href="#aes-cbc-description">23.10.1. Description</a></li><li><a href="#aes-cbc-registration">23.10.2. Registration</a></li><li><a href="#aes-cbc-params">23.10.3. AesCbcParams dictionary</a></li><li><a href="#aes-cbc-operations">23.10.4. Operations</a></li></ul></li><li><a href="#aes-gcm">23.11. AES-GCM</a><ul><li><a href="#aes-gcm-description">23.11.1. Description</a></li><li><a href="#aes-gcm-registration">23.11.2. Registration</a></li><li><a href="#aes-gcm-params">23.11.3. AesGcmParams dictionary</a></li><li><a href="#aes-gcm-operations">23.11.4. Operations</a></li></ul></li><li><a href="#hmac">23.12. HMAC</a><ul><li><a href="#hmac-description">23.12.1. Description</a></li><li><a href="#hmac-registration">23.12.2. Registration</a></li><li><a href="#hmac-params">23.12.3. HmacParams dictionary</a></li><li><a href="#hmac-operations">23.12.4. Operations</a></li></ul></li><li><a href="#dh">23.13. Diffie-Hellman</a><ul><li><a href="#dh-description">23.13.1. Description</a></li><li><a href="#dh-registration">23.13.2. Registration</a></li><li><a href="#dh-DhKeyGenParams">23.13.3. DhKeyGenParams dictionary</a></li><li><a href="#dh-DhKeyDeriveParams">23.13.4. DhKeyDeriveParams dictionary</a></li><li><a href="#dh-operations">23.13.5. Operations</a></li></ul></li><li><a href="#sha">23.14. SHA</a><ul><li><a href="#sha-description">23.14.1. Description</a></li><li><a href="#sha-registration">23.14.2. Registration</a></li><li><a href="#sha-operations">23.14.3. Operations</a></li></ul></li><li><a href="#concatkdf">23.15. Concat KDF</a><ul><li><a href="#concatkdf-description">23.15.1. Description</a></li><li><a href="#concatkdf-registration">23.15.2. Registration</a></li><li><a href="#concat-params">23.15.3. ConcatParams dictionary</a></li><li><a href="#concat-operations">23.15.4. Operations</a></li></ul></li><li><a href="#pbkdf2">23.16. PBKDF2</a><ul><li><a href="#pbkdf2-description">23.16.1. Description</a></li><li><a href="#pbkdf2-registration">23.16.2. Registration</a></li><li><a href="#pbkdf2-params">23.16.3. Pbkdf2Params dictionary</a></li><li><a href="#pbkdf2-operations">23.16.4. Operations</a></li></ul></li></ul></li><li><a href="#algorithm-normalizing-rules">24. Algorithm normalizing rules</a></li><li><a href="#examples-section">25. JavaScript Example Code</a><ul><li><a href="#examples-signing">25.1. Generate a signing key pair, sign some data</a></li><li><a href="#examples-symmetric-encryption">25.2. Symmetric Encryption</a></li></ul></li><li><a href="#acknowledgements-section">26. Acknowledgements</a></li><li><a href="#references">27. References</a><ul><li><a href="#normative-references">27.1. Normative References</a></li><li><a href="#informative-references">27.2. Informative References</a></li></ul></li></ul></div>
     </div>
 
     <div id="sections">
@@ -817,7 +817,7 @@
           <h3>11.3. Structured clone algorithm</h3>
           <p>
             When a user agent is required to obtain a <a href="#dfn-structured-clone">structured clone</a>
-            of a <a href="#dfn-Key">Key</a> object, it must run the following algorithm.
+            of a <a href="#dfn-Key">Key</a> object, it must run the following steps.
           </p>
           <ol>
             <li>
@@ -851,7 +851,6 @@
         <h2>12. CryptoOperation interface</h2>
         <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
 interface <dfn id="dfn-CryptoOperation">CryptoOperation</dfn> : <a href="#dfn-EventTarget">EventTarget</a> {
-  void <a href="#dfn-CryptoOperation-method-init">init</a>();
   void <a href="#dfn-CryptoOperation-method-process">process</a>(<a href="#dfn-ArrayBuffer">ArrayBufferView</a> buffer);
   void <a href="#dfn-CryptoOperation-method-finish">finish</a>();
   void <a href="#dfn-CryptoOperation-method-abort">abort</a>();
@@ -862,7 +861,6 @@
 
   [TreatNonCallableasNull] attribute Function? <a href="#dfn-CryptoOperation-onabort">onabort</a>;
   [TreatNonCallableAsNull] attribute Function? <a href="#dfn-CryptoOperation-onerror">onerror</a>;
-  [TreatNonCallableAsNull] attribute Function? <a href="#dfn-CryptoOperation-oninit">oninit</a>;
   [TreatNonCallableAsNull] attribute Function? <a href="#dfn-CryptoOperation-onprogress">onprogress</a>;
   [TreatNonCallableAsNull] attribute Function? <a href="#dfn-CryptoOperation-oncomplete">oncomplete</a>;
 };
@@ -879,69 +877,237 @@
             </li>
           </ul>
         </div>
-        <div id="CryptoOperation-states" class="section">
-          <h3>12.1. CryptoOperation states</h3>
+        <div id="CryptoOperation-processing-model" class="section">
+          <h3>12.1. Processing Model</h3>
           <p>
-            The <code><a href="#dfn-CryptoOperation">CryptoOperation</a></code> can be in any one of
-            five states. This state is tracked internal to the
-            <code><a href="#dfn-CryptoOperation">CryptoOperation</a></code> and may be used to
-            determine what methods may be called.
+            Every <code>CryptoOperation</code> object must have a <dfn id="dfn-CryptoOperation-list-of-pending-data">list
+            of pending data</dfn>. Each item in the lists represents data that should be transformed by the
+            cryptographic operation. The list functions as a queue that observes first-in, first-out ordering. That is,
+            the order in which items are added shall reflect the order in which items are removed.
           </p>
-          <dl>
-            <dt id="dfn-CryptoOperation-state-empty"><code>"empty"</code></dt>
-            <dd>
-              The <code>CryptoOperation</code> has been constructed, and
-              <code><a href="#dfn-CryptoOperation-method-init">init()</a></code> has not yet been called.
-              This is the default state of a newly constructed <code>CryptoOperation</code> object,
-              until <code><a href="#dfn-CryptoOperation-method-init">init()</a></code> is called.
-            </dd>
-            <dt id="dfn-CryptoOperation-state-initializing"><code>"initializing"</code></dt>
-            <dd>
-              The <code>CryptoOperation</code> is in the midst of performing necessary
-              initialization steps as the result of
-              <code><a href="#dfn-CryptoOperation-method-init">init()</a></code> being called. The
-              <code>CryptoOperation</code> is not yet ready to accept data supplied via
-              <code><a href="#dfn-CryptoOperation-method-process">process()</a></code>.
-            </dd>
-            <dt id="dfn-CryptoOperation-state-processing"><code>"processing"</code></dt>
-            <dd>
-              The <code>CryptoOperation</code> has completed initialization and is ready to process
-              data. More data to be processed may be supplied via
-              <code><a href="#dfn-CryptoOperation-method-process">process()</a></code>, or the
-              operation may be concluded by calling
-              <code><a href="#dfn-CryptoOperation-method-finish">finish()</a></code>.
-            </dd>
-            <dt id="dfn-CryptoOperation-state-completing"><code>"completing"</code></dt>
-            <dd>
-              The <code>CryptoOperation</code> is in the midst of performing the necessary finishing
-              steps to compute the final <a href="#dfn-CryptoOperation-result"><code>result</code></a>,
-              as a result of calling the <a href="#dfn-CryptoOperation-method-finish"><code>finish()</code></a>
-              method. No further data may be provided via the
-              <a href="#dfn-CryptoOperation-method-process"><code>process()</code></a>
-              method.
-            </dd>
-            <dt id="dfn-CryptoOperation-state-complete"><code>"complete"</code></dt>
-            <dd>
-              The <code>CryptoOperation</code> has finished processing data, OR an error occurred
-              during initialization, OR an error occurred during processing, OR the operation was
-              aborted using <code><a href="#dfn-CryptoOperation-method-abort">abort()</a></code>. The
-              <code>CryptoOperation</code> is no longer able to be used to process data.
-            </dd>
-          </dl>
-        </div>
-        <div id="cryptooperation-task-source" class="section">
-          <h3>12.2. The CryptoOperation Task Source</h3>
           <p>
-            The <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a> interface enables
-            asynchronous cryptographic processing by firing events. Unless stated otherwise, the
-            <a href="#task-source">task source</a> that is used in this specification is the
-            <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>. This task source is
-            used for events that are asynchronously fired, and for event <a href="#queue-a-task">
-            tasks that are queued</a> for firing.
+            When a CryptoOperation is said to <dfn id="dfn-CryptoOperation-process-data">process data</dfn>, the user
+            agent must execute the following steps:
           </p>
+          <ol>
+            <li>
+              <p>
+                If there are no items in the <a href="dfn-CryptoOperation-list-of-pending-data">list of pending
+                data</a>, the algorithm is complete.
+              </p>
+            </li>
+            <li>
+              <dl class="switch">
+                <dt>
+                  If the underlying cryptographic implementation does not support multi-part cryptographic operations for
+                  the current <a href="#dfn-CryptoOperation-algorithm">algorithm</a>, perform the following steps:
+                </dt>
+                <dd>
+                  <ol>
+                    <li>
+                      <p>
+                        Let <var>bytes</var> be an empty sequence of bytes.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        For each item in the <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>:
+                      </p>
+                      <ol>
+                        <li>
+                          <p>
+                            Let <var>item</var> be the oldest remaining item in the
+                            <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            Remove <var>item</var> from the <a href="#dfn-CryptoOperation-list-of-pending-data">list of
+                            pending data</a>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            Convert <var>item</var> to a sequence of <code>byteLength</code> bytes from the underlying
+                            <code>ArrayBuffer</code>, starting at the <code>byteOffset</code> of the <code>ArrayBufferView</code>,
+                            and append those bytes to <var>bytes</var>
+                          </p>
+                        </li>
+                      </ol>
+                    </li>
+                    <li>
+                      <p>
+                        Perform the underlying cryptographic algorithm, using <var>bytes</var> as the input data.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        If the cryptographic operation fails, proceed to the error steps below:
+                      </p>
+                      <ol>
+                        <li>
+                          <p>
+                            Update the internal state to <code>"error"</code>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            <a href="queue-a-task">Queue a task</a> to
+                            <a href="#fire-a-simple-event">fire a simple event</a> named
+                            <a href="#dfn-CryptoOperation-onerror"><code>onerror</code></a> at the
+                            <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            <a href="#terminate-an-algorithm">Terminate this algorithm</a>.
+                          </p>
+                        </li>
+                      </ol>
+                    </li>
+                    <li>
+                      <p>
+                        Let <var>output</var> be the result of the underlying cryptographic algorithm.
+                      </p>
+                    </li>
+                  </ol>
+                </dd>
+                <dt>
+                  Otherwise, if the underlying cryptographic implementation supports multi-part cryptographic operations
+                  for the current <a href="#dfn-CryptoOperation-algorithm">algorithm</a>, perform the following
+                  algorithm:
+                </dt>
+                <dd>
+                  <ol>
+                    <li>
+                      <p>
+                        Let <var>bytes</var> be an empty sequence of bytes.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        Let <var>item</var> be the oldest remaining item in the
+                        <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        Remove <var>data</var> from the <a href="#dfn-CryptoOperation-list-of-pending-data">list of
+                        pending data</a>.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        Convert <var>item</var> to a sequence of <code>byteLength</code> bytes from the underlying
+                        <code>ArrayBuffer</code>, starting at the <code>byteOffset</code> of the <code>ArrayBufferView</code>,
+                        and append those bytes to <var>bytes</var>
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        A <a href="#dfn-conforming-implementation">conforming user agent</a> <span class="RFC2119">MAY</span>
+                        repeat the preceeding steps as many times as desired, for as long as items remain in the
+                        <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>, provided that the
+                        output of the underlying cryptographic algorithm is indistinguishable from when only a single item is
+                        processed at a time.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        Perform the underlying cryptographic algorithm, using <var>bytes</var> as the input data.
+                      </p>
+                    </li>
+                    <li>
+                      <p>
+                        If the cryptographic operation fails, proceed to the error steps below:
+                      </p>
+                      <ol>
+                        <li>
+                          <p>
+                            Clear the <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            Update the internal state to <code>"error"</code>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            <a href="queue-a-task">Queue a task</a> to
+                            <a href="#fire-a-simple-event">fire a simple event</a> named
+                            <a href="#dfn-CryptoOperation-onerror"><code>onerror</code></a> at the
+                            <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>.
+                          </p>
+                        </li>
+                        <li>
+                          <p>
+                            <a href="#terminate-an-algorithm">Terminate this algorithm</a>.
+                          </p>
+                        </li>
+                      </ol>
+                    </li>
+                    <li>
+                      <p>
+                        Let <var>output</var> be the result of the underlying cryptographic algorithm.
+                      </p>
+                    </li>                  
+                  </ol>
+                </dd>
+              </dl>
+            </li>
+            <li>
+              <p>
+                Update <a href="#dfn-CryptoOperation-result"><code>result</code></a> with the algorithm-specific
+                result using <var>output</var>.
+              </p>
+              <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+                <p>
+                  The wording here is presently ambiguous. It is modeled after the [FILE API], which has <code>result</code>
+                  accumulating the output as it becomes available. However, given that support for multi-part input exists,
+                  an interface to support streaming/progressive output has also been requested. How such an interface would
+                  be implemented, if at all, remains TBD.
+                </p>
+              </div>
+            </li>
+            <li>
+              <p>
+                <a href="#fire-a-simple-event">Fire an event</a> named <a href="#dfn-CryptoOperation-onprogress"><code>onprogress</code></a>
+                at the <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>.
+              </p>
+            </li>
+            <li>
+              <p>
+                If the underlying cryptograophic implementation supports multi-part cryptographic operations for the
+                current <a href="#dfn-CryptoOperation-algorithm">algorithm</a>, repeat these steps for each item remaining
+                in the <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>.
+              </p>
+            </li>
+          </ol>
+          <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+            <ul>
+              <li>
+                <p>
+                  The above algorithm is meant to describe a possible way of supporting multi-part input (also called "streaming"
+                  input, but not to be confused with the [STREAMS API]. The downside to the above algorithm is that it does not
+                  describe a good interface for supporting algorithms that may support multiple multi-part inputs.
+                </p>
+                <p>
+                  An example of such an algorithm would be AES-GCM, which has two sources of input - the encrypted-and-authenticated
+                  data ("ciphertext") and the authenticated data ("additional authenticated data"). A truly multi-part implementation
+                  would allow both the plaintext/ciphertext and the authenticated data to be supplied independently, and in parts,
+                  until <code>finish()</code> was called.
+                </p>
+                <p>
+                  However, at present, several major cryptographic APIs (CDSA, CNG, PKCS#11) do not support this, and so for now, the
+                  details for handling multi-source multi-part data have been omitted.
+                </p>
+              </li>
+            </ul>
+          </div>
         </div>
         <div id="cryptooperation-events" class="section">
-          <h3>12.3. Event Handler Attributes</h3>
+          <h3>12.2. Event Handler Attributes</h3>
           <p>
             The following are the <a href="#event-handler-attributes">event handler attributes</a>
             (and their corresponding <a href="#event-handler-event-type">event handler event
@@ -971,10 +1137,6 @@
                 <td><a href="#dfn-onerror-event">error</a></td>
               </tr>
               <tr>
-                <td><dfn id="dfn-CryptoOperation-oninit">oninit</dfn></td>
-                <td><a href="#dfn-oninit-event">init</a></td>
-              </tr>
-              <tr>
                 <td><dfn id="dfn-CryptoOperation-onprogress">onprogress</dfn></td>
                 <td><a href="#dfn-onprogress-event">progress</a></td>
               </tr>
@@ -986,7 +1148,7 @@
           </table>
         </div>
         <div id="CryptoOperation-attributes" class="section">
-          <h3>12.4. Attributes</h3>
+          <h3>12.3. Attributes</h3>
           <dl>
             <dt id="dfn-CryptoOperation-key"><code>key</code></dt>
             <dd>
@@ -1013,16 +1175,9 @@
               <ul>
                 <li>
                   <p>
-                    On getting, if the internal state of the CryptoOperation is the
-                    <a href="#dfn-CryptoOperation-state-empty"><code>"empty"</code></a> state,
-                    then the <code>result</code> attribute <span class="RFC2119">MUST</span>
-                    return <code>null</code>.
-                  </p>
-                </li>
-                <li>
-                  <p>
                     On getting, if an error in performing the operation has occurred, then the
-                    <code>result</code> attribute <span class="RFC2119">MUST</span> return <code>null</code>.
+                    <code>result</code> attribute <span class="RFC2119">MUST</span> return
+                    <code>null</code>.
                   </p>
                 </li>
               </ul>
@@ -1030,247 +1185,99 @@
           </dl>
         </div>
         <div id="CryptoOperation-methods" class="section">
-          <h3>12.5. Methods and Parameters</h3>
-          <div id="CryptoOperation-method-init" class="section">
-            <h4>12.5.1. The <dfn id="dfn-CryptoOperation-method-init"><code>init</code></dfn> method</h4>
+          <h3>12.4. Methods</h3>
+          <div id="CryptoOperation-method-process" class="section">
+            <h4>12.4.1. <dfn id="dfn-CryptoOperation-method-process"><code>process(ArrayBufferView data)</code></dfn></h4>
             <p>
-              When <a href="#dfn-CryptoOperation-method-init"><code>init</code></a> method is called,
-              the user agent must run the steps below.
+              When the <code>process(ArrayBufferView data)</code> method is called, the user agent must run
+              the following steps:
             </p>
             <ol>
               <li>
-                If the internal <a href="#CryptoOperation-states">state</a> is not in the
-                <code><a href="#dfn-CryptoOperation-state-empty">"empty"</a></code> state,
-                throw an <code>InvalidStateError</code> exception [<a href="#DOM4">DOM4</a>] and
-                <dfn id="terminate-the-algorithm">terminate the algorithm</dfn>.
-              </li>
-              <li>
-                Set the internal <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-initializing">"initializing"</a></code>.
-              </li>
-              <li>
-                Return from the <code>init()</code> method, but continue processing the steps in this
-                algorithm.
+                <p>
+                  If the internal state is in the <code>"error"</code> state, throw an
+                  <code>InvalidStateError</code> exception and abort these steps.
+                </p>
               </li>
               <li>
-                If an error occurs during initialization, set the internal
-                <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-complete">complete</a></code> and set
-                <code><a href="#dfn-CryptoOperation-result">result</a></code> to null. Proceed to the
-                error steps below.
-                <ol>
-                  <li>
-                    Fire an event called <code><a href="#dfn-onerror-event">error</a></code>.
-                  </li>
-                  <li>
-                    Terminate this algorithm.
-                  </li>
-                </ol>
+                <p>
+                  Let <var>data</var> be the data to be processed.
+                </p>
               </li>
               <li>
-                When the <code>CryptoOperation</code> is fully initialized, set the
-                <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-processing">processing</a></code>.
+                <p>
+                  Add <var>data</var> to the <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a>.
+                </p>
               </li>
               <li>
-                Fire an event called <code><a href="#dfn-oninit-event">init</a></code>.
-              </li>
-              <li>
-                Terminate this algorithm.
+                <p>
+                  If the underlying cryptographic implementation for the specified
+                  <a href="#dfn-CryptoOperation-algorithm">algorithm</a> supports multi-part cryptographic operations,
+                  asynchrously <a href="#dfn-CryptoOperation-process-data">process data</a>, allowing the task that
+                  invoked this algorithm to continue.
+                </p>
+                <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+                  <p>
+                    Warning: The text here is currently ambiguous in terms of defining how the <code>event loop</code>
+                    processes events; in particular, it leaves under-specified how the <a href="#dfn-CryptoOperation-method-abort">
+                    <code>abort()</code></a> method should be handled when data is being processed.
+                  </p>
+                </div>
               </li>
             </ol>
           </div>
-          <div id="CryptoOperation-method-process" class="section">
-            <h4>12.5.2. The <dfn id="dfn-CryptoOperation-method-process"><code>process(ArrayBufferView buffer)</code></dfn> method</h4>
-            <p>
-              When <a href="#dfn-CryptoOperation-method-process"><code>process(ArrayBufferView buffer)</code></a>
-              method is called, the user agent must run the steps below.
-            </p>
-            <ol>
-              <li>
-                If the internal <a href="#CryptoOperation-states">state</a> is not in the
-                <code><a href="#dfn-CryptoOperation-state-processing">"processing"</a></code> state,
-                throw an <code>InvalidStateError</code> exception [<a href="#DOM4">DOM4</a>] and
-                <dfn id="terminate-the-algorithm">terminate the algorithm</dfn>.
-              </li>
-              <li>
-                Return from the <code>process()</code> method, but continue processing the steps in
-                this algorithm.
-              </li>
-              <li>
-                If an error occurs during processing, set the internal
-                <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-complete">complete</a></code> and set
-                <code><a href="#dfn-CryptoOperation-result">result</a></code> to null. Proceed to the
-                error steps below.
-                <ol>
-                  <li>
-                    Fire an event called <code><a href="#dfn-onerror-event">error</a></code>.
-                  </li>
-                  <li>
-                    Terminate this algorithm.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Perform the algorithm-specific processing.
-              </li>
-              <li>
-                If processing resulted in <code>output</code>, perform the following steps.
-                <ol>
-                  <li>
-                    Queue a task to update <code><a href="#dfn-CryptoOperation-result">result</a></code>
-                    with the <code>output</code>
-                  </li>
-                  <li>
-                    Fire an event called <code><a href="#dfn-onprogress-event">progress</a></code>.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Terminate this algorithm.
-              </li>
-            </ol>          
-          </div>
           <div id="CryptoOperation-method-finish" class="section">
-            <h4>12.5.3. The <dfn id="dfn-CryptoOperation-method-finish"><code>finish()</code></dfn> method</h4>
+            <h4>12.4.2. The <dfn id="dfn-CryptoOperation-method-finish"><code>finish()</code></dfn> method</h4>
             <p>
               When <a href="#dfn-CryptoOperation-method-finish"><code>finish()</code></a>
               method is called, the user agent must run the steps below.
             </p>
             <ol>
               <li>
-                If the internal <a href="#CryptoOperation-states">state</a> is not in the
-                <code><a href="#dfn-CryptoOperation-state-processing">"processing"</a></code> state,
-                throw an <code>InvalidStateError</code> exception [<a href="#DOM4">DOM4</a>] and
-                <dfn id="terminate-the-algorithm">terminate the algorithm</dfn>.
-              </li>
-              <li>
-                Set the internal <a href="#CryptoOperation-states">state</a> to
-                <a href="#dfn-CryptoOperation-state-completing"><code>completing</code></a>.
-              </li>
-              <li>
-                Return from the <code>finish()</code> method, but continue processing the steps in
-                this algorithm.
+                <p>
+                  If the internal state is in the <code>"error"</code> state, throw an
+                  <code>InvalidStateError</code> exception and abort these steps.
+                </p>
               </li>
               <li>
-                If an error occurs during processing, set the internal
-                <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-complete">complete</a></code> and set
-                <code><a href="#dfn-CryptoOperation-result">result</a></code> to null. Proceed to the
-                error steps below.
-                <ol>
-                  <li>
-                    Fire an event called <code><a href="#dfn-onerror-event">error</a></code>.
-                  </li>
-                  <li>
-                    Terminate this algorithm.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Perform the algorithm-specific processing.
+                <p>
+                  Set the internal state to <code>"complete"</code>.
+                </p>
               </li>
               <li>
-                Let <var>output</var> be the result of the algorithm-specific processing.
-              </li>
-              <li>
-                Queue a task to update <code><a href="#dfn-CryptoOperation-result">result</a></code>
-                with the <var>output</var>
+                <p>
+                  If the underlying cryptographic implementation for the specified
+                  <a href="#dfn-CryptoOperation-algorithm">algorithm</a> does not support multi-part cryptographic
+                  operations, asynchronously <a href="#dfn-CryptoOperation-process-data">process data</a>, allowing the task
+                  that invoked this algorithm to continue.
+                </p>
               </li>
               <li>
-                Fire an event called <code><a href="#dfn-onprogress-event">progress</a></code>.
-              </li>
-              <li>
-                Set the internal <a href="#CryptoOperation-states">state</a> to
-                <code><a href="#dfn-CryptoOperation-state-complete">complete</a></code>.
-              </li>
-              <li>
-                Fire an event called <code><a href="#dfn-oncomplete-event">complete</a></code>.
-              </li>
-              <li>
-                Terminate this algorithm.
+                <p>
+                  Once all items in the <a href="#dfn-CryptoOperation-list-of-pending-data">list of pending data</a> have
+                  been <a href="#dfn-CryptoOperation-process-data">processed</a>, <a href="#queue-a-task">queue a task</a>
+                  to <a href="#fire-a-simple-event">fire an event</a> called
+                  <a href="#dfn-CryptoOperation-oncomplete"><code>oncomplete</code></a> at the
+                  <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>.
+                </p>
               </li>
             </ol>
           </div>
           <div id="CryptoOperation-method-abort" class="section">
-            <h4>12.5.4. The <dfn id="dfn-CryptoOperation-method-abort"><code>abort()</code></dfn> method</h4>
+            <h4>12.4.3. The <dfn id="dfn-CryptoOperation-method-abort"><code>abort()</code></dfn> method</h4>
             <p>
               When <a href="#dfn-CryptoOperation-method-abort"><code>abort()</code></a>
               method is called, the user agent must run the steps below.
             </p>
             <ol>
               <li>
-                If the internal <a href="#CryptoOperation-states">state</a> is either
-                <a href="#dfn-CryptoOperation-state-empty"><code>"empty"</code></a> or
-                <a href="#dfn-CryptoOperation-state-complete"><code>"complete"</code></a>, set
-                <a href="#dfn-CryptoOperation-result"><code>result</code></a> to <code>null</code>
-                and terminate this overall set of steps without doing anything else.
-              </li>
-              <li>
                 <p>
-                  If the internal <a href="#CryptoOperation-states">state</a> is
-                  <a href="#dfn-CryptoOperation-state-initializing"><code>"initializing"</code></a>,
-                  then perform the following steps:
+                  If the internal state is in the <code>"error"</code> state, throw an
+                  <code>InvalidStateError</code> exception and abort these steps.
                 </p>
-                <ol>
-                  <li>
-                    Set the internal <a href="#CryptoOperation-states">state</a> to
-                    <a href="#dfn-CryptoOperation-state-complete"><code>"complete"</code></a>.
-                  </li>
-                  <li>
-                    Set <a href="#dfn-CryptoOperation-result"><code>result</code></a> to
-                    <code>null</code>.
-                  </li>
-                  <li>
-                    <a href="#terminate-the-algorithm">Terminate the algorithm</a> for the
-                    <a href="#dfn-CryptoOperation-method-init"><code>init()</code></a> method.
-                  </li>
-                </ol>
               </li>
               <li>
-                <p>
-                  If the internal <a href="#CryptoOperation-states">state</a> is
-                  <a href="#dfn-CryptoOperation-state-processing"><code>"processing"</code></a>,
-                  then perform the following steps:
-                </p>
-                <ol>
-                  <li>
-                    Set the internal <a href="#CryptoOperation-states">state</a> to
-                    <a href="#dfn-CryptoOperation-state-complete"><code>"complete"</code></a>.
-                  </li>
-                  <li>
-                    Set <a href="#dfn-CryptoOperation-result"><code>result</code></a> to
-                    <code>null</code>.
-                  </li>
-                  <li>
-                    <a href="#terminate-the-algorithm">Terminate the algorithm</a> for the
-                    <a href="#dfn-CryptoOperation-method-process"><code>process()</code></a>
-                    method.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                <p>
-                  If the internal <a href="#CryptoOperation-states">state</a> is
-                  <a href="#dfn-CryptoOperation-state-completing"><code>"completing"</code></a>,
-                  then perform the following steps:
-                </p>
-                <ol>
-                  <li>
-                    Set the internal <a href="#CryptoOperation-states">state</a> to
-                    <a href="#dfn-CryptoOperation-state-complete"><code>"complete"</code></a>.
-                  </li>
-                  <li>
-                    Set <a href="#dfn-CryptoOperation-result"><code>result</code></a> to
-                    <code>null</code>.
-                  </li>
-                  <li>
-                    <a href="#terminate-the-algorithm">Terminate the algorithm</a> for the
-                    <a href="#dfn-CryptoOperation-method-finish"><code>finish()</code></a>
-                    method.
-                  </li>
-                </ol>
+                <p>Abort <a href="#dfn-CryptoOperation-process-data">processing data</a>.</p>
               </li>
               <li>
                 If there are any tasks from the object's
@@ -1281,6 +1288,11 @@
                 Fire an event called <a href="#dfn-onabort-event"><code>abort</code></a>.
               </li>
             </ol>
+            <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+              <p>
+                The above algorithm is underspecified.
+              </p>
+            </div>
           </div>
         </div>
       </div>