implications of different CDM types

420 views
Skip to first unread message

Nelson Kidd

unread,
Jul 2, 2015, 11:54:10 AM7/2/15
to chromi...@chromium.org
Hi,

I've read that 3 types of CDM exist for Chromium, and I would like to confirm and expand my understanding of the implications of these CDM types.
  • Internal from source (Clear Key, which is implemented internally by aes_decryptor.cc)
  • Pepper-based CDMs (used for desktop and Chrome OS)
  • Platform-based (e.g. Android using MediaDrm APIs)

[Internal from source]
  1. This CDM type allows unrestricted access to the platform. Calling LoadLibrary() or interacting with drivers directly is permitted. 
  2. This option is works if you are deploying specifically with a fork of the Chromium browser. 
  3. Plugging into other browsers (Chrome, Firefox, IE, etc.) effectively requires a similar business arrangement as Adobe Flash (difficult to arrange). 

[Pepper-based CDM]
  1. This CDM type provides a path to other browsers using the CDM, as long as the other browser implements PPAPI and EME. 
  2. PPAPI, even with NaCl, restricts the methods that you can call. Attempting to LoadLibrary() or interacting with drivers won't work. 
  3. A CDM that implements content_decryption_module.h but breaks trust rules could be built to work with its own fork of Chromium. This would allow updates of the CDM, without updating the browser. Plugging this kind of "bad trust Pepper CDM" into other browsers (Chrome, Firefox, IE, etc.) effectively requires a similar business arrangement as Adobe Flash (difficult to arrange). 

[Platform-based CDM]
  1. Is this CDM type reserved for Android and/or Widevine?
  2. If it's not reserved, where can I find more information about when this CDM type should be used and what restrictions are placed on it?

Thanks in advance for your insights.

PhistucK

unread,
Jul 3, 2015, 11:18:33 AM7/3/15
to nelso...@gmail.com, Chromium-dev

On Thu, Jul 2, 2015 at 6:54 PM, Nelson Kidd <nelso...@gmail.com> wrote:
PPAPI, even with NaCl, restricts the methods that you can call. Attempting to LoadLibrary() or interacting with drivers won't work. 

Note that this is inaccurate. PPAPI does not restrict anything, it is an API. Native Client does have those restrictions. PPAPI does not have to use Native Client. However​, non Native Client based PPAPI plugins are hard coded into the browser (or can be loaded by command line flags). This does mean that they do not work out of the box.



PhistucK

Ryan Sleevi

unread,
Jul 3, 2015, 11:33:25 AM7/3/15
to PhistucK Productions, nelso...@gmail.com, Chromium-dev
It's accurate in implementation, but not accurate in why.

The limitations - and preventions against things like LoadLibrary - are a consequence of the general Chrome sandboxing model. You can talk PPAPI to unsandboxed things, but part of the reason why PPAPI exists to begin with is to provide a suitable API for plugins that still allows you to fully sandbox things. 

Jesse Gunsch

unread,
Jul 6, 2015, 12:20:36 PM7/6/15
to nelso...@gmail.com, chromium-dev
I can comment briefly on platform-based CDMs:

This is not reserved for Android. Chromecast (Linux and Android builds) uses platform-based CDMs, and Chromecast uses it to support both PlayReady and Widevine. [1]

There's an assertion within Chromium that "distinctive identifier" and "persistent state" (unprefixed EME concepts) must be allowed for platform-based CDMs, I believe under the assumption that a platform CDM can't be forcibly restricted from doing either of these things. [2]

If you want to poke around using that code path, I'd probably point you toward BrowserCdmFactory [3] for providing CDMs, and BrowserCdmManager [4] as a center-point of the actual implementation.

 

Thanks in advance for your insights.

--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev

Xiaohan Wang (王消寒)

unread,
Jul 6, 2015, 7:51:44 PM7/6/15
to gun...@chromium.org, nelso...@gmail.com, chromium-dev
The different CDM types we have is really a result of Chromium's multi-process architecture, sandbox policies and security concerns than anything else.

The easiest way to develop a CDM is to implement it directly in the render process. However, there are two major limitations in this model:
  • Since the render process is sandboxed (unless you disable it), you have restrictions on what you can do. For example, you cannot load an arbitrary shared library in the sandbox.
  • We don't want to run untrusted code in the render process for security reasons. For example, a CDM may contain closed-source third-party code.
The AesDecryptor implements the Clear Key key system. It doesn't require anything out of the sandbox and is fully open source. That's why we have no problem running it in the render process. Clear Key could also be implemented via one of the other mechanisms (for example, see the External Clear Key test CDM), but this is the simplest mechanism for production use. AesDecryptor is really an exception and this CDM model is not something that is likely to be used for other key systems.

When possible, it is best to run the CDM in a separate sandboxed process. Chromium currently uses Pepper APIs for this purpose, but this is an implementation detail and Pepper is not the “CDM API”. The actual CDM is hosted within a wrapper that calls the content_decryption_module.h interface. This API is more stable but not guaranteed not to change over time.

On platforms where the DRM is implemented in the platform (e.g. Android) or the CDM needs platform support (e.g. talk to some driver), the “CDM” needs to call platform APIs. Thus, the renderer must IPC to a higher-privilege process, such as the browser process. For this, we have the BrowserCdm path. On Android, the privileged side of the IPC uses the Android MediaDrm APIs, but other platforms will have different implementations. MediaDrm is an Android API that supports whichever MediaDrm plugins that ship with the platform. However, the detailed behavior of these plugins is not specified, so the Android app (i.e. Chromium) needs to know how to use each plugin implementation. Chromium includes support for the Widevine MediaDrm plugin.

Xiaohan

Nelson Kidd

unread,
Jul 7, 2015, 6:49:19 PM7/7/15
to chromi...@chromium.org, gun...@chromium.org, nelso...@gmail.com

When possible, it is best to run the CDM in a separate sandboxed process. Chromium currently uses Pepper APIs for this purpose, but this is an implementation detail and Pepper is not the “CDM API”. The actual CDM is hosted within a wrapper that calls the content_decryption_module.h interface. This API is more stable but not guaranteed not to change over time.

Am I correct in my assumption that the external clear-key CDM provides a basic implementation of this technique?
 

 or the CDM needs platform support (e.g. talk to some driver), the “CDM” needs to call platform APIs. Thus, the renderer must IPC to a higher-privilege process, such as the browser process. For this, we have the BrowserCdm path. 

The prototyping scenario I have sounds more along these lines. I was under the impression that I could use the external clear-key CDM as the hook for facilitating this, but maybe I'm going about this the wrong way. Could you comment on whether the technique below would even work on Windows Chromium?
  1. HTML5/JS declares an instance of a custom-DRM plugin. 
  2. Chromium interprets the HTML5/JS and instantiates an instance of my Pepper Plugin, which embodies the CDM.
  3. Chromium, in an ongoing manner, keeps the Pepper Plugin CDM appraised of the required render location for the video.
  4. My Pepper Plugin CDM allocates any necessary D3D11 surfaces to comply with the location requirements from [3] and any security/protection requirements from the DRM. (It's not clear to me whether I should allocate the surface in the Pepper Plugin CDM or in my elevated process.)
  5. My Pepper Plugin CDM passes the D3D11 surface(s) to a different/elevated process (e.g. a Windows Service) over IPC. If I need to talk to drivers or other privileged functions, they would probably reside in this privileged Windows Service process, so as to not burden the chrome process or the sandboxed CDM with a requirement to run in an elevated manner. Drawing to the surface happens in this elevated process in a secure manner, as demanded by any DRM robustness rules.

Xiaohan Wang (王消寒)

unread,
Jul 7, 2015, 7:44:51 PM7/7/15
to Nelson Kidd, chromium-dev, gun...@chromium.org
CIL

On Tue, Jul 7, 2015 at 3:49 PM, Nelson Kidd <nelso...@gmail.com> wrote:

When possible, it is best to run the CDM in a separate sandboxed process. Chromium currently uses Pepper APIs for this purpose, but this is an implementation detail and Pepper is not the “CDM API”. The actual CDM is hosted within a wrapper that calls the content_decryption_module.h interface. This API is more stable but not guaranteed not to change over time.

Am I correct in my assumption that the external clear-key CDM provides a basic implementation of this technique?

Yes. The ClearKeyCdm is an example using this approach.  

 or the CDM needs platform support (e.g. talk to some driver), the “CDM” needs to call platform APIs. Thus, the renderer must IPC to a higher-privilege process, such as the browser process. For this, we have the BrowserCdm path. 

The prototyping scenario I have sounds more along these lines. I was under the impression that I could use the external clear-key CDM as the hook for facilitating this, but maybe I'm going about this the wrong way. Could you comment on whether the technique below would even work on Windows Chromium?
  1. HTML5/JS declares an instance of a custom-DRM plugin. 
  2. Chromium interprets the HTML5/JS and instantiates an instance of my Pepper Plugin, which embodies the CDM.
The pepper plugin part is really an implementation details of EME in Chromium. The JS won't have a way to declare or communicate with the CDM directly. The only way to load and use the CDM from JS is through the EME API.
  1. Chromium, in an ongoing manner, keeps the Pepper Plugin CDM appraised of the required render location for the video.
  2. My Pepper Plugin CDM allocates any necessary D3D11 surfaces to comply with the location requirements from [3] and any security/protection requirements from the DRM. (It's not clear to me whether I should allocate the surface in the Pepper Plugin CDM or in my elevated process.)
  3. My Pepper Plugin CDM passes the D3D11 surface(s) to a different/elevated process (e.g. a Windows Service) over IPC. If I need to talk to drivers or other privileged functions, they would probably reside in this privileged Windows Service process, so as to not burden the chrome process or the sandboxed CDM with a requirement to run in an elevated manner. Drawing to the surface happens in this elevated process in a secure manner, as demanded by any DRM robustness rules.
I am not super clear how your systems works here. But if you already launches a privileged process to do most of the work, you probably don't want to use pepper based CDM. Running a BrowserCdm sounds a better choice.

How will the media pipeline look like in your system? Will the CDM handle all the decryption, decoding and rendering? If so, there's a (new) path to support customized media pipeline/CDM in the browser process, or a different child process (e.g. utility process). If you are interested in this path, you can take a look at MojoMediaApplication and ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS.

--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev

To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.

Nelson Kidd

unread,
Jul 7, 2015, 9:02:37 PM7/7/15
to chromi...@chromium.org, nelso...@gmail.com, gun...@chromium.org
How will the media pipeline look like in your system? Will the CDM handle all the decryption, decoding and rendering? 

No. About the only thing the CDM will do is marshall parameters from HTML5/JS and EME to an external process. Thanks for the lead on MOJO. I'll take a look at it.

-nkidd

Nelson Kidd

unread,
Jul 8, 2015, 5:22:38 PM7/8/15
to chromi...@chromium.org, nelso...@gmail.com, gun...@chromium.org
If so, there's a (new) path to support customized media pipeline/CDM in the browser process, or a different child process (e.g. utility process). If you are interested in this path, you can take a look at MojoMediaApplication and ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS.

I set enable_mojo_media = "browser" in media_options.gni, cleaned, and rebuilt "chrome" and "mojo" as targets. When I launch chrome.exe, I see mojo_environment_chromium_impl.dll, mojo_system_impl.dll, mojo_common_lib.dll, and ipc_mojo.dll get loaded, based on Visual Studio output window.

Setting breakpoints on lines in mojo_media_application.cc doesn't work. I suspect that mojo_media_application.cc is part of a target that I did not build. I tried "mojo_native_application" (based on info in major_application.gni) but that didn't work. 

I also tried setting in conditionally-compiled MOJO lines such as (render_frame_impl or mojo_shell_context.cc), but Visual Studio complains. This suggests that I didn't build or link something correctly.  

Can you provide guidance as to what I am missing and doing incorrectly?

-nkidd

Nelson Kidd

unread,
Jul 8, 2015, 5:25:32 PM7/8/15
to chromi...@chromium.org, nelso...@gmail.com
Also, what .html file or webpage should I use to ensure the execution path goes to MojoMediaApplication?

Xiaohan Wang (王消寒)

unread,
Jul 8, 2015, 5:32:05 PM7/8/15
to Nelson Kidd, chromium-dev
Are you making a GN build instead of a gyp build? The new mojo media application path is only supported in GN builds.

With enable_mojo_media = "browser", all HTML5 <video> will use the mojo media application in the browser process. The default video renderer is a fake one so you won't see anything, but audio should work. I suppose you'll want to replace the fake video renderer with what you described earlier...

On Wed, Jul 8, 2015 at 2:25 PM, Nelson Kidd <nelso...@gmail.com> wrote:
Also, what .html file or webpage should I use to ensure the execution path goes to MojoMediaApplication?

--

Nelson Kidd

unread,
Jul 8, 2015, 6:43:37 PM7/8/15
to chromi...@chromium.org, nelso...@gmail.com
Ah. OK. I did not realize there were separate GN and GYP build processes. 

Out of curiosity, do EME-related transactions flow between Chrome/EME and MojoMediaApplication, or is MojoMediaApplication only wired up to handle basic windowing placement and input events? I noticed references to CDM in the code, but I am not sure if those are just stubs.

Xiaohan Wang (王消寒)

unread,
Jul 8, 2015, 6:56:05 PM7/8/15
to Nelson Kidd, chromium-dev
CDM functionalities are fully wired to and supported by MojoMediaApplication. What you need to do is to provide a CdmFactory for your own CDM implementation (well, after my CL lands).

media::Renderer is also fully supported in MojoMediaApplication. Similarly, you'll need to provide a RendererFactory() for your own implementation.

Note that media::Renderer basically provides an interface to feed compressed audio/video buffers to a client, and get some basic information back (e.g. current media time) to support the HTML5 <video> implementation. It's the clients responsibility to decide how to decode those buffers and how to render them. That being said, there's no native "windowing placement and input events" support. You'll probably want to handle that by yourself.


On Wed, Jul 8, 2015 at 3:43 PM, Nelson Kidd <nelso...@gmail.com> wrote:
Ah. OK. I did not realize there were separate GN and GYP build processes. 

Out of curiosity, do EME-related transactions flow between Chrome/EME and MojoMediaApplication, or is MojoMediaApplication only wired up to handle basic windowing placement and input events? I noticed references to CDM in the code, but I am not sure if those are just stubs.

--
Message has been deleted

Nelson Kidd

unread,
Jul 8, 2015, 8:00:38 PM7/8/15
to chromi...@chromium.org, nelso...@gmail.com
Are you making a GN build instead of a gyp build? The new mojo media application path is only supported in GN builds.

OK. That explains things. I did make a GYP build.

I've tried making a GN build, but documentation suggests it only works on Linux. Running "gn gen out/MojoBuild" results in KeyError: 'GYP_MSVS_OVERRIDE_PATH'. 

If I set GYP_MSVS_OVERRIDE_PATH="C:/Program Files (x86)/Microsoft Visual Studio 12.0" and  GYP_MSVS_VERSION="2013", I encounter the following error.

ERROR at dynamically parsed input that //build/config/win/visual_studio_version.
gni:27:7 loaded :1:15: Invalid token.
vs_path = ""C:/Program Files (x86)/Microsoft Visual Studio 12.0""
              ^
I have no idea what this is.

Is GN expected to work for Chrome/Pepper/MOJO targets on Windows right now?

Xiaohan Wang (王消寒)

unread,
Jul 8, 2015, 8:17:58 PM7/8/15
to Nelson Kidd, bre...@chromium.org, chromium-dev
I never tried GN build on Windows, but it should be supported.

+brettw for GN specific questions.

--

Nelson Kidd

unread,
Jul 9, 2015, 2:38:08 PM7/9/15
to chromi...@chromium.org, nelso...@gmail.com, bre...@chromium.org
Xiaohan,

Thanks again for all of your help. I'll wait and see if brettw has any suggestions for GN on windows.
Reply all
Reply to author
Forward
0 new messages