[EME] Bug 17202 - Only keys in sessions from the MediaKeys associated with the media element may be used for decryption.
authorDavid Dorwin <ddorwin@google.com>
Tue, 25 Mar 2014 14:43:32 -0700
changeset 267 151f30f76656
parent 266 b72845be0c8c
child 268 48643033a3f5
[EME] Bug 17202 - Only keys in sessions from the MediaKeys associated with the media element may be used for decryption.
encrypted-media/encrypted-media.html
encrypted-media/encrypted-media.xml
--- a/encrypted-media/encrypted-media.html	Tue Mar 25 14:40:33 2014 -0700
+++ b/encrypted-media/encrypted-media.html	Tue Mar 25 14:43:32 2014 -0700
@@ -245,13 +245,17 @@
     </p>
 
     <h4 id="key-session">1.1.3. Key Session</h4>
-    <p>A Key Session, or simply Session, represents the lifetime of the key(s) it contains and associates all messages related to them.
+    <p>A Key Session, or simply Session, represents the lifetime of the license(s)/key(s) it contains and associates all messages related to them.
     Sessions are embodied as <code><a href="#dom-mediakeysession">MediaKeySession</a></code> objects.
     Each Key session is associated with a single instance of <a href="#initialization-data">Initialization Data</a> provided in the <code><a href="#dom-createsession">createSession()</a></code> call.
     </p>
+    <p>Each Key Session is associated with a single <code><a href="#dom-mediakeys">MediaKeys</a></code> object, and only <a href="#media-element">media elements</a> associated with that object may access key(s) associated with the session.
+    Other <code><a href="#dom-mediakeys">MediaKeys</a></code> objects, <a href="#cdm">CDM</a> instances, and media elements may <em>not</em> access the key session or use its key(s).
+    Key sessions and the keys they contain are no longer usable by the CDM for decryption when the <a href="#algorithms-session-close">session is closed</a>, including when the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object is destroyed.
+    </p>
 
     <h4 id="session-id">1.1.4. Session ID</h4>
-    <p>A Session ID is a unique string identifier generated by the user agent or CDM that can be used by the application to identify <code><a href="#dom-mediakeysession">MediaKeySession</a></code> objects.
+    <p>A Session ID is a unique string identifier generated by the user agent or <a href="#cdm">CDM</a> that can be used by the application to identify <code><a href="#dom-mediakeysession">MediaKeySession</a></code> objects.
     <span class="non-normative">(The underlying content protection client or server do not necessarily need to support Session IDs.)</span>
     </p>
 
@@ -360,9 +364,9 @@
         <ol>
           <li><p>Let <var title="true">cdm</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</p></li>
           <li><p>Load and initialize the <var title="true">cdm</var> if necessary.</p></li>
-          <li><p>If <var title="true">cdm</var> fails to load or initialize, store the appropriate <a href="#mediakeyerror-names">error name</a> and system code internally with the <code><a href="#dom-mediakeys">MediaKeys</a></code> instance being created.
+          <li><p>If <var title="true">cdm</var> fails to load or initialize, save the appropriate <a href="#mediakeyerror-names">error name</a> and system code internally with the <code><a href="#dom-mediakeys">MediaKeys</a></code> instance being created.
           This will be used to fire an error against the first session created for this instance.
-          If no system code is provided, store 0.
+          If no system code is provided, use 0.
           </p></li>
         </ol>
       </li>
@@ -401,10 +405,10 @@
         <ol>
           <li><p>Wait for the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task to complete.</p></li>
           <li>
-<p>If error information is stored with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object because of an error during the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task:</p>
+<p>If error information is saved with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object because of an error during the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task:</p>
             <ol>
-              <li><p>Run the <a href="#algorithms-queue-error">Queue an "error" Event</a> algorithm on the <var title="true">session</var>, providing the <a href="#mediakeyerror-names">error name</a> and system code that were stored with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object.</p></li>
-              <li><p>Clear the error information stored with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object.</p></li>
+              <li><p>Run the <a href="#algorithms-queue-error">Queue an "error" Event</a> algorithm on the <var title="true">session</var>, providing the <a href="#mediakeyerror-names">error name</a> and system code that were saved with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object.</p></li>
+              <li><p>Clear the error information saved with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object.</p></li>
               <li><p>Abort the task.</p></li>
             </ol>
           </li>
@@ -412,7 +416,7 @@
           <li><p>Let <var title="true">default URL</var> be null.</p></li>
           <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
           <li>
-<p>Use <var title="true">cdm</var> to execute the following steps:</p>
+<p>Use the <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
               <li><p>Process the <var title="true">initData</var>, interpreting it per <var title="true">initDataFormat</var>.</p></li>
               <li>
@@ -489,10 +493,10 @@
         <ol>
           <li><p>Wait for the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task to complete.</p></li>
           <li>
-<p>If error information is stored with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object because of an error during the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task:</p>
+<p>If error information is saved with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object because of an error during the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task:</p>
             <ol>
-              <li><p>Run the <a href="#algorithms-queue-error">Queue an "error" Event</a> algorithm on the <var title="true">session</var>, providing the <a href="#mediakeyerror-names">error name</a> and system code that were stored with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object.</p></li>
-              <li><p>Clear the error information stored with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object.</p></li>
+              <li><p>Run the <a href="#algorithms-queue-error">Queue an "error" Event</a> algorithm on the <var title="true">session</var>, providing the <a href="#mediakeyerror-names">error name</a> and system code that were saved with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object.</p></li>
+              <li><p>Clear the error information saved with the <code><a href="#dom-mediakeys">MediaKeys</a></code> object.</p></li>
               <li><p>Abort the task.</p></li>
             </ol>
           </li>
@@ -501,7 +505,7 @@
           <li><p>Let <var title="true">origin</var> be the <a href="http://www.w3.org/TR/html5/browsers.html#origin-0">origin</a> of the <code><a href="#dom-mediakeys">MediaKeys</a></code> object's <code><a href="http://www.w3.org/TR/dom/#document">Document</a></code>.</p></li>
           <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
           <li>
-<p>Use <var title="true">cdm</var> to execute the following steps:</p>
+<p>Use the <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
               <li>
 <p>If there is no data stored for the <var title="true">sessionId</var> in the <var title="true">origin</var>, run the following steps:</p>
@@ -603,13 +607,13 @@
           <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
           <li><p>Let <var title="true">request</var> be null.</p></li>
           <li>
-<p>Use <var title="true">cdm</var> to execute the following steps:</p>
+<p>Use the <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
               <li>
 <p>Process <var title="true">response</var>.</p>
-                <p class="non-normative">Note: When <var title="true">response</var> contains key(s) and/or related data, <var title="true">cdm</var> will likely store the key and related data indexed by key ID.</p>
+                <p class="non-normative">Note: When <var title="true">response</var> contains key(s) and/or related data, <var title="true">cdm</var> will likely cache the key and related data indexed by key ID.</p>
                 <p class="non-normative">Note: The replacement algorithm within a session is <a href="#key-system">Key System</a>-dependent.</p>
-                <p class="non-normative">Note: Keys from different sessions should be stored independently such that closing one session does not affect keys in other sessions, even if they have overlapping key IDs.</p>
+                <p class="non-normative">Note: Keys from different sessions should be cached independently such that closing one session does not affect keys in other sessions, even if they have overlapping key IDs.</p>
                 <p class="non-normative">Note: It is recommended that CDMs support a standard and reasonably high minimum number of keys per <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object, including a standard replacement algorithm, and a standard and reasonably high minimum number of <code><a href="#dom-mediakeysession">MediaKeySession</a></code> objects.
                 This enables a reasonable number of key rotation algorithms to be implemented across user agents and may reduce the likelihood of playback interruptions in use cases that involve various streams in the same element (i.e. adaptive streams, various audio and video tracks) using different keys.
                 </p>
@@ -660,7 +664,7 @@
         <ol>
           <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
           <li>
-<p>Use <var title="true">cdm</var> to execute the following steps:</p>
+<p>Use the <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
               <li>
                 <p>Process the release request.</p>
@@ -933,26 +937,32 @@
       <li>
 <p>If the media element's <code><a href="#dom-attrmediakeys">mediaKeys</a></code> attribute is not null, run the following steps:</p>
         <ol>
-          <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
+          <li><p>Let <var title="true">media keys</var> be the <code><a href="#dom-mediakeys">MediaKeys</a></code> object referenced by that atribute.</p></li>
+          <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded during the <a href="#dom-mediakeys-constructor">initialization</a> of the <var title="true">media keys</var>.</p></li>
           <li>
-<p>If <var title="true">cdm</var> has at least one <code><a href="#dom-mediakeysession">MediaKeySession</a></code> in the <code><a href="#dom-statepending">PENDING</a></code> or <code><a href="#dom-stateready">READY</a></code> state, run the following steps:</p>
+<p>If at least one <code><a href="#dom-mediakeysession">MediaKeySession</a></code> created by the <var title="true">media keys</var> is in the <code><a href="#dom-statepending">PENDING</a></code> or <code><a href="#dom-stateready">READY</a></code> state, run the following steps:</p>
             <p class="non-normative">This check ensures the <var title="true">cdm</var> has finished loading and is a prequisite for a matching key being available.</p>
             <ol>
-              <li><p>Let <var title="true">block key ID</var> be the key ID of the current block <span class="non-normative">(as specified by the container)</span>.</p></li>
+              <li><p>Let the <var title="true">block key ID</var> be the key ID of the current block <span class="non-normative">(as specified by the container)</span>.</p></li>
               <li>
-<p>Use <var title="true">cdm</var> to decrypt the block by following the steps for the first matching condition from the following list:</p>
+<p>Use the <var title="true">cdm</var> to execute the following steps:</p>
+                <ol>
+                  <li><p>Let <var title="true">available keys</var> be the union of keys in sessions that were created by the <var title="true">media keys</var>.</p></li>
+                  <li>
+<p>Follow the steps for the first matching condition from the following list:</p>
+                
                 <p class="non-normative">In the following steps, a key is considered usable if it is valid as determined by the CDM. For example, a key is not usable if its license has expired.</p>
                 <dl class="switch">
-                <dt>If any session has a usable key for <var title="">block key ID</var>
-</dt>
+                <dt>If any of the <var title="true">available keys</var> corresponds to the <var title="">block key ID</var> and is usable</dt>
                 <dd>Run the following steps:
                   <ol>
                     <li>
 <p>Let <var title="">block key</var> be the matching key.</p>
-                      <p class="non-normative">Note: If multiple sessions contain a <em>usable</em> key for <var title="">block key ID</var>, which session is used is <a href="#key-system">Key System</a>-dependent.</p>
+                      <p class="non-normative">Note: If multiple sessions contain a <em>usable</em> key for the <var title="">block key ID</var>, which key to use is <a href="#key-system">Key System</a>-dependent.</p>
                     </li>
+                    <li><p>Use the <var title="true">cdm</var> to decrypt the block using <var title="">block key</var>.</p></li>
                     <li>
-<p>Use <var title="true">cdm</var> to decrypt the block using <var title="">block key</var> by following the steps for the first matching condition from the following list:</p>
+<p>Follow the steps for the first matching condition from the following list:</p>
                       <dl class="switch">
                         <dt>If decryption fails</dt>
                         <dd>Abort the media element's <a href="http://www.w3.org/TR/html5/embedded-content-0.html#concept-media-load-resource">resource fetch algorithm</a>, run the steps to report a <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#dom-mediaerror-media_err_decode">MEDIA_ERR_DECODE</a></code> error, and abort these steps.</dd>
@@ -964,8 +974,7 @@
                     </li>
                   </ol>
                 </dd>
-                <dt>If any session has an unusable key for <var title="">block key ID</var>
-</dt>
+                <dt>If any of the <var title="true">available keys</var> corresponds to the <var title="">block key ID</var> and is unusable</dt>
                 <dd>Run the following steps:
                   <ol>
                     <li><p>Let <var title="true">session</var> be the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object associated with that session.</p></li>
@@ -973,9 +982,11 @@
                     <li><p>Abort these steps.</p></li>
                   </ol>
                 </dd>
-                <dt><span class="non-normative">Otherwise (there is no key for <var title="true">block key ID</var> in any session)</span></dt>
-                <dd><span class="non-normative">Continue.</span></dd>
+                <dt class="non-normative">Otherwise (there is no key for the <var title="true">block key ID</var> in any session)</dt>
+                <dd class="non-normative">Continue.</dd>
                 </dl>
+                  </li>
+                </ol>
               </li>
             </ol>
           </li>
@@ -1146,20 +1157,38 @@
     <p>The presence or use of Key Systems on a user's device raises a number of privacy issues, falling into two categories: (a) user-specific information that may be disclosed by the EME interface itself, or within messages from Key Systems and (b) user-specific information that may be persistently stored on the users device.</p>
     <p>User Agents should take responsibility for providing users with adequate control over their own privacy. Since User Agents may integrate with third party CDM implementations, CDM implementers must provide sufficient information and controls to user agent implementers to enable them to implement appropriate techniques to ensure users have control over their privacy, including but not limited to the techniques described below.</p>
 
-    <h3 id="privacy-disclosure">7.1. Information disclosed by EME and Key Systems</h3>
+    <h3 id="privacy-disclosure">7.1. Information Disclosed by EME and Key Systems</h3>
     <p>Concerns regarding information disclosed by EME and Key Systems fall into two categories, concerns about non-specific information that may nevertheless contribute to the possibility of fingerprinting a user agent or device and user-specific information that may be used directly for user tracking.</p>
 
     <h4 id="privacy-fingerprinting">7.1.1 Fingerprinting</h4>
     <p>Malicious applications may be able to fingerprint users or user agents by detecting or enumerating the list of key systems that are supported and related information. If proper origin protections are not provided this could include detection of sites that have been visited and information stored for those sites. In particular, Key Systems should not share key or other data between sites that are not CORS-same-origin.</p>
 
-    <h4 id="privacy-tracking">7.1.2 Tracking</h4>
+    <h4 id="privacy-tracking">7.1.2 Information Leakage</h4>
+    <p>CDMs, especially those implemented outside the user agent, may not have the same fundamental isolations as the web platform.
+    It is important that steps be taken to avoid information leakage, especially across origins.
+    This includes both in-memory and stored data.
+    Failure to do so could lead to information leakage to/from Incognito/Private Browsing sessions, across profiles, and even across different operating system user accounts.
+    </p>
+    
+    <p>To avoid such issues, user agent and CDM implementations should ensure that:</p>
+    <ul>
+      <li>CDMs have a concept of a CDM instance that is associated 1:1 with a MediaKeys object.</li>
+      <li>Keys, licenses, other session data, and the presence of sessions are restricted to the the CDM instance associated with the MediaKeys object that created the session.</li>
+      <li>Session data is not shared between MediaKeys objects or CDM instances.</li>
+      <li>Session data is not shared with media elements not associated with the MediaKeys object that created the session. Among other things, this means a session's keys may not be used to decrypt content loaded by a media element whose <code><a href="#dom-attrmediakeys">mediaKeys</a></code> attribute is not the MediaKeys object.</li>
+      <li>MediaKeys objects and the underlying implementation do not expose information outside the origin.</li>
+      <li>Persisted session data, if applicable, is stored on a per-origin basis.</li>
+      <li>Only data stored by the requesting origin may be loaded.</li>
+    </ul>
+
+    <h4 id="privacy-tracking">7.1.3 Tracking</h4>
     <p>User-specific information may be obtained over the EME API in two ways: through detection of stored keys and through Key System messages.</p>
 
     <p>Key Systems may access or create persistent or semi-persistent identifiers for a device or user of a device. In some cases these identifiers may be bound to a specific device in a secure manner. If these identifiers are present in Key System messages, then devices and/or users may be tracked. If the mitigations below are not applied this could include both tracking of users / devices over time and associating multiple users of a given device. If not mitigated, such tracking may take three forms depending on the design of the Key System:</p>
     <ul>
-      <li>in all cases, such identifiers are expected to be available to sites and/or servers that fully support the Key System (and thus can interpret Key System messages) enabling tracking by such sites.</li>
-      <li>if identifiers exposed by Key Systems are not origin-specific, then two sites and/or servers that fully support the Key System may collude to track the user</li>
-      <li>if a Key System messages contains information derived from a user identifier in a consistent manner, for example such that a portion of the initial Key System message for a specific content item does not change over time and is dependent on the user identifier, then this information could be used by any application to track the device or user over time.</li>
+      <li>In all cases, such identifiers are expected to be available to sites and/or servers that fully support the Key System (and thus can interpret Key System messages) enabling tracking by such sites.</li>
+      <li>If identifiers exposed by Key Systems are not origin-specific, then two sites and/or servers that fully support the Key System may collude to track the user</li>
+      <li>If a Key System messages contains information derived from a user identifier in a consistent manner, for example such that a portion of the initial Key System message for a specific content item does not change over time and is dependent on the user identifier, then this information could be used by any application to track the device or user over time.</li>
     </ul>
 
     <p>If a Key System permits keys to be stored and to be re-used between origins, then it may be possible for two origins to collude and track a unique user by recording their ability to access a common key.</p>
@@ -1196,14 +1225,14 @@
     <p>It is important to note that identifiers that are non-clearable, non-origin-specific or hardware-bound exceed the tracking impact of existing techniques such as Cookies or session identifiers embedded in URLs.</p>
     <p>Thus, in addition to the various mitigations described above, if a browser supports a mode of operation intended to preserve user anonymity, then User Agent implementers should carefully consider whether access to Key Systems should be disabled in this mode.</p>
 
-    <h3 id="privacy-storedinfo">7.2. Information stored on user devices</h3>
+    <h3 id="privacy-storedinfo">7.2. Information Stored on User Devices</h3>
     <p>Key Systems may store information on a user's device, or user agents may store information on behalf of Key Systems. Potentially, this could reveal information about a user to another user of the same device, including potentially the origins that have used a particular Key System (i.e. sites visited) or even the content that has been decrypted using a Key System.</p>
     <p>If information stored by one origin affects the operation of the Key System for another origin, then potentially the sites visited or content viewed by a user on one site may be revealed to another, potentially malicious, site.</p>
     <p>There are a number of techniques that can be used to mitigate these privacy risk to users:</p>
 
     <dl>
       <dt>Origin-specific Key System storage</dt>
-      <dd>User agents may require that some or all of the Key System's persistently stored data is stored in an origin-specific way.</dd>
+      <dd>User agents may require that some or all of the Key System's persistently stored data is stored in an origin-specific way. Session data, licenses, and keys that are persistently stored should be stored per-origin.</dd>
 
       <dt>User deletion of Key System storage</dt>
       <dd>User agents may present the user with a way to delete Key System storage for a specific origin or all origins.</dd>
--- a/encrypted-media/encrypted-media.xml	Tue Mar 25 14:40:33 2014 -0700
+++ b/encrypted-media/encrypted-media.xml	Tue Mar 25 14:43:32 2014 -0700
@@ -242,13 +242,17 @@
     </p>
 
     <h4 id="key-session">1.1.3. Key Session</h4>
-    <p>A Key Session, or simply Session, represents the lifetime of the key(s) it contains and associates all messages related to them.
+    <p>A Key Session, or simply Session, represents the lifetime of the license(s)/key(s) it contains and associates all messages related to them.
     Sessions are embodied as <coderef>MediaKeySession</coderef> objects.
     Each Key session is associated with a single instance of <a href="#initialization-data">Initialization Data</a> provided in the <methodref>createSession</methodref> call.
     </p>
+    <p>Each Key Session is associated with a single <coderef>MediaKeys</coderef> object, and only <a href="#media-element">media elements</a> associated with that object may access key(s) associated with the session.
+    Other <coderef>MediaKeys</coderef> objects, <a href="#cdm">CDM</a> instances, and media elements may <em>not</em> access the key session or use its key(s).
+    Key sessions and the keys they contain are no longer usable by the CDM for decryption when the <a href="#algorithms-session-close">session is closed</a>, including when the <coderef>MediaKeySession</coderef> object is destroyed.
+    </p>
 
     <h4 id="session-id">1.1.4. Session ID</h4>
-    <p>A Session ID is a unique string identifier generated by the user agent or CDM that can be used by the application to identify <coderef>MediaKeySession</coderef> objects.
+    <p>A Session ID is a unique string identifier generated by the user agent or <a href="#cdm">CDM</a> that can be used by the application to identify <coderef>MediaKeySession</coderef> objects.
     <span class="non-normative">(The underlying content protection client or server do not necessarily need to support Session IDs.)</span>
     </p>
 
@@ -357,9 +361,9 @@
         <ol>
           <li><p>Let <var title="true">cdm</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</p></li>
           <li><p>Load and initialize the <var title="true">cdm</var> if necessary.</p></li>
-          <li><p>If <var title="true">cdm</var> fails to load or initialize, store the appropriate <a href="#mediakeyerror-names">error name</a> and system code internally with the <coderef>MediaKeys</coderef> instance being created.
+          <li><p>If <var title="true">cdm</var> fails to load or initialize, save the appropriate <a href="#mediakeyerror-names">error name</a> and system code internally with the <coderef>MediaKeys</coderef> instance being created.
           This will be used to fire an error against the first session created for this instance.
-          If no system code is provided, store 0.
+          If no system code is provided, use 0.
           </p></li>
         </ol>
       </li>
@@ -396,17 +400,17 @@
         <p>The user agent will asynchronously execute the following steps in the task:</p>
         <ol>
           <li><p>Wait for the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task to complete.</p></li>
-          <li><p>If error information is stored with the <coderef>MediaKeys</coderef> object because of an error during the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task:</p>
+          <li><p>If error information is saved with the <coderef>MediaKeys</coderef> object because of an error during the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task:</p>
             <ol>
-              <li><p>Run the <a href="#algorithms-queue-error">Queue an "error" Event</a> algorithm on the <var title="true">session</var>, providing the <a href="#mediakeyerror-names">error name</a> and system code that were stored with the <coderef>MediaKeys</coderef> object.</p></li>
-              <li><p>Clear the error information stored with the <coderef>MediaKeys</coderef> object.</p></li>
+              <li><p>Run the <a href="#algorithms-queue-error">Queue an "error" Event</a> algorithm on the <var title="true">session</var>, providing the <a href="#mediakeyerror-names">error name</a> and system code that were saved with the <coderef>MediaKeys</coderef> object.</p></li>
+              <li><p>Clear the error information saved with the <coderef>MediaKeys</coderef> object.</p></li>
               <li><p>Abort the task.</p></li>
             </ol>
           </li>
           <li><p>Let <var title="true">request</var> be null.</p></li>
           <li><p>Let <var title="true">default URL</var> be null.</p></li>
           <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
-          <li><p>Use <var title="true">cdm</var> to execute the following steps:</p>
+          <li><p>Use the <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
               <li><p>Process the <var title="true">initData</var>, interpreting it per <var title="true">initDataFormat</var>.</p></li>
               <li><p>If a message exchange <span class="non-normative">(e.g. a license request)</span> is required:</p>
@@ -476,10 +480,10 @@
         <p>The user agent will asynchronously execute the following steps in the task:</p>
         <ol>
           <li><p>Wait for the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task to complete.</p></li>
-          <li><p>If error information is stored with the <coderef>MediaKeys</coderef> object because of an error during the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task:</p>
+          <li><p>If error information is saved with the <coderef>MediaKeys</coderef> object because of an error during the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a> task:</p>
             <ol>
-              <li><p>Run the <a href="#algorithms-queue-error">Queue an "error" Event</a> algorithm on the <var title="true">session</var>, providing the <a href="#mediakeyerror-names">error name</a> and system code that were stored with the <coderef>MediaKeys</coderef> object.</p></li>
-              <li><p>Clear the error information stored with the <coderef>MediaKeys</coderef> object.</p></li>
+              <li><p>Run the <a href="#algorithms-queue-error">Queue an "error" Event</a> algorithm on the <var title="true">session</var>, providing the <a href="#mediakeyerror-names">error name</a> and system code that were saved with the <coderef>MediaKeys</coderef> object.</p></li>
+              <li><p>Clear the error information saved with the <coderef>MediaKeys</coderef> object.</p></li>
               <li><p>Abort the task.</p></li>
             </ol>
           </li>
@@ -487,7 +491,7 @@
           <li><p>Let <var title="true">destination URL</var> be null.</p></li>
           <li><p>Let <var title="true">origin</var> be the <a href="http://www.w3.org/TR/html5/browsers.html#origin-0">origin</a> of the <coderef>MediaKeys</coderef> object's <code><dom4ref name="document">Document</dom4ref></code>.</p></li>
           <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
-          <li><p>Use <var title="true">cdm</var> to execute the following steps:</p>
+          <li><p>Use the <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
               <li><p>If there is no data stored for the <var title="true">sessionId</var> in the <var title="true">origin</var>, run the following steps:</p>
                 <ol>
@@ -583,12 +587,12 @@
         <ol>
           <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
           <li><p>Let <var title="true">request</var> be null.</p></li>
-          <li><p>Use <var title="true">cdm</var> to execute the following steps:</p>
+          <li><p>Use the <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
               <li><p>Process <var title="true">response</var>.</p>
-                <p class="non-normative">Note: When <var title="true">response</var> contains key(s) and/or related data, <var title="true">cdm</var> will likely store the key and related data indexed by key ID.</p>
+                <p class="non-normative">Note: When <var title="true">response</var> contains key(s) and/or related data, <var title="true">cdm</var> will likely cache the key and related data indexed by key ID.</p>
                 <p class="non-normative">Note: The replacement algorithm within a session is <a href="#key-system">Key System</a>-dependent.</p>
-                <p class="non-normative">Note: Keys from different sessions should be stored independently such that closing one session does not affect keys in other sessions, even if they have overlapping key IDs.</p>
+                <p class="non-normative">Note: Keys from different sessions should be cached independently such that closing one session does not affect keys in other sessions, even if they have overlapping key IDs.</p>
                 <p class="non-normative">Note: It is recommended that CDMs support a standard and reasonably high minimum number of keys per <coderef>MediaKeySession</coderef> object, including a standard replacement algorithm, and a standard and reasonably high minimum number of <coderef>MediaKeySession</coderef> objects.
                 This enables a reasonable number of key rotation algorithms to be implemented across user agents and may reduce the likelihood of playback interruptions in use cases that involve various streams in the same element (i.e. adaptive streams, various audio and video tracks) using different keys.
                 </p>
@@ -635,7 +639,7 @@
         <p>The user agent will asynchronously execute the following steps in the task:</p>
         <ol>
           <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
-          <li><p>Use <var title="true">cdm</var> to execute the following steps:</p>
+          <li><p>Use the <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
               <li>
                 <p>Process the release request.</p>
@@ -895,21 +899,27 @@
     <ol>
       <li><p>If the media element's <coderef prefix="attr">mediaKeys</coderef> attribute is not null, run the following steps:</p>
         <ol>
-          <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-mediakeys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
-          <li><p>If <var title="true">cdm</var> has at least one <coderef>MediaKeySession</coderef> in the <coderef prefix="state">PENDING</coderef> or <coderef prefix="state">READY</coderef> state, run the following steps:</p>
+          <li><p>Let <var title="true">media keys</var> be the <coderef>MediaKeys</coderef> object referenced by that atribute.</p></li>
+          <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded during the <a href="#dom-mediakeys-constructor">initialization</a> of the <var title="true">media keys</var>.</p></li>
+          <li><p>If at least one <coderef>MediaKeySession</coderef> created by the <var title="true">media keys</var> is in the <coderef prefix="state">PENDING</coderef> or <coderef prefix="state">READY</coderef> state, run the following steps:</p>
             <p class="non-normative">This check ensures the <var title="true">cdm</var> has finished loading and is a prequisite for a matching key being available.</p>
             <ol>
-              <li><p>Let <var title="true">block key ID</var> be the key ID of the current block <span class="non-normative">(as specified by the container)</span>.</p></li>
-              <li><p>Use <var title="true">cdm</var> to decrypt the block by following the steps for the first matching condition from the following list:</p>
+              <li><p>Let the <var title="true">block key ID</var> be the key ID of the current block <span class="non-normative">(as specified by the container)</span>.</p></li>
+              <li><p>Use the <var title="true">cdm</var> to execute the following steps:</p>
+                <ol>
+                  <li><p>Let <var title="true">available keys</var> be the union of keys in sessions that were created by the <var title="true">media keys</var>.</p></li>
+                  <li><p>Follow the steps for the first matching condition from the following list:</p>
+                <!-- TODO: Fix indentation. -->
                 <p class="non-normative">In the following steps, a key is considered usable if it is valid as determined by the CDM. For example, a key is not usable if its license has expired.</p>
                 <dl class="switch">
-                <dt>If any session has a usable key for <var title="">block key ID</var></dt>
+                <dt>If any of the <var title="true">available keys</var> corresponds to the <var title="">block key ID</var> and is usable</dt>
                 <dd>Run the following steps:
                   <ol>
                     <li><p>Let <var title="">block key</var> be the matching key.</p>
-                      <p class="non-normative">Note: If multiple sessions contain a <em>usable</em> key for <var title="">block key ID</var>, which session is used is <a href="#key-system">Key System</a>-dependent.</p>
+                      <p class="non-normative">Note: If multiple sessions contain a <em>usable</em> key for the <var title="">block key ID</var>, which key to use is <a href="#key-system">Key System</a>-dependent.</p>
                     </li>
-                    <li><p>Use <var title="true">cdm</var> to decrypt the block using <var title="">block key</var> by following the steps for the first matching condition from the following list:</p>
+                    <li><p>Use the <var title="true">cdm</var> to decrypt the block using <var title="">block key</var>.</p></li>
+                    <li><p>Follow the steps for the first matching condition from the following list:</p>
                       <dl class="switch">
                         <dt>If decryption fails</dt>
                         <dd>Abort the media element's <resource-fetch-algorithm/>, run the steps to report a <videoref name="dom-mediaerror-media_err_decode">MEDIA_ERR_DECODE</videoref> error, and abort these steps.</dd>
@@ -920,7 +930,7 @@
                     </li>
                   </ol>
                 </dd>
-                <dt>If any session has an unusable key for <var title="">block key ID</var></dt>
+                <dt>If any of the <var title="true">available keys</var> corresponds to the <var title="">block key ID</var> and is unusable</dt>
                 <dd>Run the following steps:
                   <ol>
                     <li><p>Let <var title="true">session</var> be the <coderef>MediaKeySession</coderef> object associated with that session.</p></li>
@@ -928,9 +938,11 @@
                     <li><p>Abort these steps.</p></li>
                   </ol>
                 </dd>
-                <dt><span class="non-normative">Otherwise (there is no key for <var title="true">block key ID</var> in any session)</span></dt>
-                <dd><span class="non-normative">Continue.</span></dd>
+                <dt class="non-normative">Otherwise (there is no key for the <var title="true">block key ID</var> in any session)</dt>
+                <dd class="non-normative">Continue.</dd>
                 </dl>
+                  </li>
+                </ol>
               </li>
             </ol>
           </li>
@@ -1097,20 +1109,38 @@
     <p>The presence or use of Key Systems on a user's device raises a number of privacy issues, falling into two categories: (a) user-specific information that may be disclosed by the EME interface itself, or within messages from Key Systems and (b) user-specific information that may be persistently stored on the users device.</p>
     <p>User Agents should take responsibility for providing users with adequate control over their own privacy. Since User Agents may integrate with third party CDM implementations, CDM implementers must provide sufficient information and controls to user agent implementers to enable them to implement appropriate techniques to ensure users have control over their privacy, including but not limited to the techniques described below.</p>
 
-    <h3 id="privacy-disclosure">7.1. Information disclosed by EME and Key Systems</h3>
+    <h3 id="privacy-disclosure">7.1. Information Disclosed by EME and Key Systems</h3>
     <p>Concerns regarding information disclosed by EME and Key Systems fall into two categories, concerns about non-specific information that may nevertheless contribute to the possibility of fingerprinting a user agent or device and user-specific information that may be used directly for user tracking.</p>
 
     <h4 id="privacy-fingerprinting">7.1.1 Fingerprinting</h4>
     <p>Malicious applications may be able to fingerprint users or user agents by detecting or enumerating the list of key systems that are supported and related information. If proper origin protections are not provided this could include detection of sites that have been visited and information stored for those sites. In particular, Key Systems should not share key or other data between sites that are not CORS-same-origin.</p>
 
-    <h4 id="privacy-tracking">7.1.2 Tracking</h4>
+    <h4 id="privacy-tracking">7.1.2 Information Leakage</h4>
+    <p>CDMs, especially those implemented outside the user agent, may not have the same fundamental isolations as the web platform.
+    It is important that steps be taken to avoid information leakage, especially across origins.
+    This includes both in-memory and stored data.
+    Failure to do so could lead to information leakage to/from Incognito/Private Browsing sessions, across profiles, and even across different operating system user accounts.
+    </p>
+    
+    <p>To avoid such issues, user agent and CDM implementations should ensure that:</p>
+    <ul>
+      <li>CDMs have a concept of a CDM instance that is associated 1:1 with a MediaKeys object.</li>
+      <li>Keys, licenses, other session data, and the presence of sessions are restricted to the the CDM instance associated with the MediaKeys object that created the session.</li>
+      <li>Session data is not shared between MediaKeys objects or CDM instances.</li>
+      <li>Session data is not shared with media elements not associated with the MediaKeys object that created the session. Among other things, this means a session's keys may not be used to decrypt content loaded by a media element whose <coderef prefix="attr">mediaKeys</coderef> attribute is not the MediaKeys object.</li>
+      <li>MediaKeys objects and the underlying implementation do not expose information outside the origin.</li>
+      <li>Persisted session data, if applicable, is stored on a per-origin basis.</li>
+      <li>Only data stored by the requesting origin may be loaded.</li>
+    </ul>
+
+    <h4 id="privacy-tracking">7.1.3 Tracking</h4>
     <p>User-specific information may be obtained over the EME API in two ways: through detection of stored keys and through Key System messages.</p>
 
     <p>Key Systems may access or create persistent or semi-persistent identifiers for a device or user of a device. In some cases these identifiers may be bound to a specific device in a secure manner. If these identifiers are present in Key System messages, then devices and/or users may be tracked. If the mitigations below are not applied this could include both tracking of users / devices over time and associating multiple users of a given device. If not mitigated, such tracking may take three forms depending on the design of the Key System:</p>
     <ul>
-      <li>in all cases, such identifiers are expected to be available to sites and/or servers that fully support the Key System (and thus can interpret Key System messages) enabling tracking by such sites.</li>
-      <li>if identifiers exposed by Key Systems are not origin-specific, then two sites and/or servers that fully support the Key System may collude to track the user</li>
-      <li>if a Key System messages contains information derived from a user identifier in a consistent manner, for example such that a portion of the initial Key System message for a specific content item does not change over time and is dependent on the user identifier, then this information could be used by any application to track the device or user over time.</li>
+      <li>In all cases, such identifiers are expected to be available to sites and/or servers that fully support the Key System (and thus can interpret Key System messages) enabling tracking by such sites.</li>
+      <li>If identifiers exposed by Key Systems are not origin-specific, then two sites and/or servers that fully support the Key System may collude to track the user</li>
+      <li>If a Key System messages contains information derived from a user identifier in a consistent manner, for example such that a portion of the initial Key System message for a specific content item does not change over time and is dependent on the user identifier, then this information could be used by any application to track the device or user over time.</li>
     </ul>
 
     <p>If a Key System permits keys to be stored and to be re-used between origins, then it may be possible for two origins to collude and track a unique user by recording their ability to access a common key.</p>
@@ -1147,14 +1177,14 @@
     <p>It is important to note that identifiers that are non-clearable, non-origin-specific or hardware-bound exceed the tracking impact of existing techniques such as Cookies or session identifiers embedded in URLs.</p>
     <p>Thus, in addition to the various mitigations described above, if a browser supports a mode of operation intended to preserve user anonymity, then User Agent implementers should carefully consider whether access to Key Systems should be disabled in this mode.</p>
 
-    <h3 id="privacy-storedinfo">7.2. Information stored on user devices</h3>
+    <h3 id="privacy-storedinfo">7.2. Information Stored on User Devices</h3>
     <p>Key Systems may store information on a user's device, or user agents may store information on behalf of Key Systems. Potentially, this could reveal information about a user to another user of the same device, including potentially the origins that have used a particular Key System (i.e. sites visited) or even the content that has been decrypted using a Key System.</p>
     <p>If information stored by one origin affects the operation of the Key System for another origin, then potentially the sites visited or content viewed by a user on one site may be revealed to another, potentially malicious, site.</p>
     <p>There are a number of techniques that can be used to mitigate these privacy risk to users:</p>
 
     <dl>
       <dt>Origin-specific Key System storage</dt>
-      <dd>User agents may require that some or all of the Key System's persistently stored data is stored in an origin-specific way.</dd>
+      <dd>User agents may require that some or all of the Key System's persistently stored data is stored in an origin-specific way. Session data, licenses, and keys that are persistently stored should be stored per-origin.</dd>
 
       <dt>User deletion of Key System storage</dt>
       <dd>User agents may present the user with a way to delete Key System storage for a specific origin or all origins.</dd>