Common Encryption (CENC)

The Common Encryption Scheme (CENC) specifies standard encryption and key mapping methods that can be utilized by one or more digital rights and key management systems (DRM systems) to enable decryption of the same file using different DRM systems.

The scheme operates by defining a common format for the encryption related metadata necessary to decrypt the protected streams, yet leaves the details of rights mappings, key acquisition and storage, DRM compliance rules, etc. up to the DRM system or systems supporting CENC.

The ISO/IEC 23001-7 standard defines four Common Encryption modes:

Mode Full Sample Encryption Pattern Encryption
AES CTR 'cenc' 'cens'
AES CBC 'cbc1' 'cbcs'

Using the cbcs scheme

New in version 1.10.16.

By default, encryption for DASH output uses the Common Encryption 'cenc' scheme. To override this behaviour you can use the commonEncryptionScheme attribute for a <ContentKey> element in a CPIX document. For more information, see CPIX Document Requirements. Or refer to our tutorial about setting up Multi-DRM protected HLS and DASH from a shared CMAF source.

Options for CENC

--mpd.inline_drm

Signals to put the encryption headers in both the client manifest (the .mpd file requested by DASH players) and the initialization segment.

More concretely, the client manifest will have the following additional information:

<!-- PlayReady -->
<ContentProtection
  xmlns="urn:mpeg:dash:schema:mpd:2011"
  schemeIdUri="urn:uuid:9A04F079-9840-4286-AB92-E65BE0885F95"
  value="MSPR 2.0">
  <pssh xmlns="urn:mpeg:cenc:2013">BASE64_PSSH</pssh>
  <IsEncrypted>1</IsEncrypted>
  <IV_Size xmlns="urn:microsoft:playready">8</IV_Size>
  <kid xmlns="urn:microsoft:playready">BASE64_KID</kid>
  <pro xmlns="urn:microsoft:playready">BASE64_DATA</pro>
</ContentProtection>
<!-- Widevine -->
<ContentProtection
  schemeIdUri="urn:uuid:EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED">
  <pssh xmlns="urn:mpeg:cenc:2013">BASE64_PSSH</pssh>
</ContentProtection>

The following example creates a server manifest file including the DRM information which the Origin will use to encrypt the output, using --mpd.inline_drm will add the signalling to the MPD as in previous example.

#!/bin/bash

KID=key-id-in-hex
CEK=content-key-in-hex
WV_PSSH=BASE64_PSSH_BOX

mp4split -o test.ism \
  --widevine.key=${KID}:${CEK} \
  --widevine.drm_specific_data=${WV_PSSH} \
  --mpd.inline_drm \
  tears-of-steel-400k.ismv

Multi DRM

The CENC scheme specifies standard encryption and key mapping methods that can be utilized by one or more digital rights management (DRM) and key management systems to enable decryption of the same file using different DRM systems. Such an approach supports a broader range of accessible clients from a single content stream.

The scheme operates by defining a common format for the encryption related metadata necessary to decrypt the protected streams, yet leaves the details of rights mappings, key acquisition and storage, DRM compliance rules, etc. up to the DRM system or systems supporting CENC, enabling multi-DRM protection for adaptive streaming.

Attention

For multi DRM to work with different key providers (Widevine and PlayReady for example), the same key id and content key must be used with all the key providers, e.g the Widevine content key and key id must be the same as the PlayReady content key and key id.

The CENC IBC demo features simultaneous PlayReady and Verimatrix encryption from the same MPEG-DASH URL to both Android and iOS players,

In the following example PlayReady is signalled, but this will create additional signalling for Marlin and Widevine as well so a player can pick the one it understands.

#!/bin/bash

KID=10000000100010001000100000000001
CEK=3a2a1b68dd2bd9b2eeb25e84c4776668
KID_UUID=10000000-1000-1000-1000-100000000001 #UUID representation of KID
CEK_B64="OiobaN0r2bLusl6ExHdmaA==" #Base64 byte array representation of CEK

PLAYREADY_LA_URL="https://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(kid:$KID_UUID,contentkey:$CEK_B64,ckt:aesctr)"
WV_PSSH=BASE64_PSSH_BOX #Add Widevine DRM specific data

mp4split -o test.ism \
  --iss.key=${KID}:${CEK} \
  --iss.license_server_url=${PLAYREADY_LA_URL} \
  test.ismv

The above command line will create the following signalling in the .mpd generated:

<!-- Common Encryption -->
<ContentProtection
  schemeIdUri="urn:mpeg:dash:mp4protection:2011"
  value="cenc"
  cenc:default_KID="8D1A585A-A0B4-A942-917A-C1B659142B2A">
</ContentProtection>
<!-- PlayReady -->
<ContentProtection
  schemeIdUri="urn:uuid:9A04F079-9840-4286-AB92-E65BE0885F95">
</ContentProtection>
<!-- Widevine -->
<ContentProtection
  schemeIdUri="urn:uuid:EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED">
</ContentProtection>
<!-- Marlin -->
<ContentProtection
  schemeIdUri="urn:uuid:5E629AF5-38DA-4063-8977-97FFBD9902D4">
...

Attention

Please note this only works when signalling just Playready, signalling Widevine or Marlin or combining DRMs will not add other CENC DRM signalling.

However, there are other use cases as well:

  • non CENC multi DRM
  • Widevine, Playready or Marlin only (non conforming players)
  • a specific order in the DRM signaling (non conforming players)

If you are not using CENC and PIFF (Multi DRM) but you do require multiple DRMs (or just one) then you would need to provide the individual DRM options by using Content Protection Information eXchange (CPIX), as the following CPIX document shows:

<?xml version='1.0' encoding='UTF-8'?>
<CPIX xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:dashif:org:cpix" xsi:schemaLocation="urn:dashif:org:cpix cpix.xsd">
  <ContentKeyList>
    <ContentKey kid="e82f184c-3aaa-57b4-ace8-606b5e3febad">
      <Data>
        <pskc:Secret>
          <pskc:PlainValue>wvr2bihSzExKdR8KKpQf2w==</pskc:PlainValue>
        </pskc:Secret>
      </Data>
    </ContentKey>
  </ContentKeyList>
  <DRMSystemList>
    <!-- Widevine -->
    <DRMSystem kid="e82f184c-3aaa-57b4-ace8-606b5e3febad" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
      <PSSH>AAAAMnBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABIiCnVzcHd2dGVzdDNI49yVmwY=</PSSH>
      <ContentProtectionData />
    </DRMSystem>
    <!-- Marlin -->
    <DRMSystem kid="e82f184c-3aaa-57b4-ace8-606b5e3febad" systemId="5e629af5-38da-4063-8977-97ffbd9902d4">
      <ContentProtectionData>PE1hcmxpbkNvbnRlbnRJZHMKICB4bWxucz0idXJuOm1hcmxpbjptYXM6MS0wOnNlcnZpY2VzOnNjaGVtYXM6bXBkIj4KICA8TWFybGluQ29udGVudElkPnVybjptYXJsaW46a2lkOmU4MmYxODRjM2FhYTU3YjRhY2U4NjA2YjVlM2ZlYmFkPC9NYXJsaW5Db250ZW50SWQ+CjwvTWFybGluQ29udGVudElkcz4K</ContentProtectionData>
    </DRMSystem>
  </DRMSystemList>
</CPIX>

In case a specific order is required it is possible to rewrite or filter the manifest by using Manifest Edit.