https://serverless.industries/2024/05/31/digital-cinema.en.html
* Latest posts
* Archive
* Tags
* Guides
* Projects
* Search
* RSS Feed
* Share
This post is related to the project Digital Cinema Talk.
How DCI Movie Delivery and Encryption works
31. May 2024 * christian * digital cinema, projects, reverse
engineering, security
The Cinema Industry is using its own standards for creating and
distributing movies in a secure way. The DCI (Digital Cinema
Initiatives) specification defines everything from file formats and
encryption to the projection systems itself.
The specification itself is publicly available but relies on various
IEEE (Institute of Electrical and Electronics Engineers) and SMPTE
(Society of Motion Picture and Television Engineers) standards, which
have to be purchased.
Scope
This document will show a rough overview of the DCI workflow and
describe in detail how the encryption of a DCI movie works. It will
not show how to break any encryption and no encryption has been
broken while writing this document. From our perspective, the DCI
standard is safe.
The author of this document has been operating a cinema since 2021,
without any insight to the distribution or production side of the
industry. Some information may be incomplete.
How it's started
End of 2023 the movie WONKA was released. Some cinemas reported, that
they are unable to start this movie on their projector.
The reason was, that a certificate used by the distributor was
expired. This certificate was used to sign the DCP files.
The distributor published new files, starting the movie worked again.
Out of curiosity the author started to check how the validation
process on the projector is working.
Glossar
* DCP: Digital Cinema Package - A folder which contains all
components of a movie. Metadata, Subtitles, Audio and Picture in
seperate files
* CPL: Composition Playlist - A DCP can contain multiple audio and
video streams which will combined in a CPL
* KDM: Key Delivery Message - A XML file which contains the
cryptographical information to allow a movie playback on a
specific DCI certified projection system
* DKDM: Distribution Key Delivery Message - Similar to a KDM, but
for a remastering or distribution system, not for a projection
system
Distribution Process
graph TD
classDef red fill:#a91900
classDef green fill:#126500
classDef purple fill:#650072
legendprod[Producer]:::red
legenddist[Distributor]:::green
legendcine[Cinema]:::purple
legendvendors[Projector Manufacturer]
graph LR
classDef red fill:#a91900
classDef green fill:#126500
classDef purple fill:#650072
dcpcreated(["DCP\ncreated"]):::red --"AES Key"--> dkdmcreated
dkdmcreated(["DKDM\ncreated"]):::red --"encrypted\nAES Key"--> dkdmp
dkdmp[DKDM]:::green --> verify(["Projector\nverified"]):::green
dcpcreated --"to Distributor"--> dcp(["DCP by\nDownload or\nHarddrive"]):::green
distcert["Distributor\nCertificate"]:::green --"to Producer"--> dkdmcreated
verify --"to Cinema"--> kdm[KDM]:::purple
dcp --"to Cinema"--> dcp2["DCP"]:::purple
cinecert["Projector\nCertificate"]:::purple --"to Distributor"--> verify
trusted["Trusted Device List"] --> verify
dcp2 --> projector[Projector]:::purple
kdm --> projector
Projection Systems
Most of the Projection Systems consists of Server, Audio Processor
and Projector.
graph LR
server[Server] --> mediablock[Media Block]
hdmi[HDMI Source] --> splitter[Audio Splitter]
splitter --"Video"--> projector
splitter --"Audio"--> sound
subgraph Projector
mediablock --"Video"--> projector[Projector]
end
projector --> screen[Theatre Screen]
mediablock --"Audio"--> sound[Audio Processor]
sound --> speakers[Speakers]
The Server stores the DCPs and KDMs, manages Playlists and controls
the Projector and Audio Processor hardware.
Many Cinemas also connect their Theatre Automation (light, curtains,
etc.) to the projector. By setting time-based commands into the
playlists, lights and screen curtain can be controlled automatically.
The Projector Server provides 12V/24V relays for this.
These time-based commands are also used to set the correct Aspect
Ratio and Volume on the different DCPs in a Playlist.
The Server can be controlled remotely by a PC or in larger cinemas by
a Theatre Management System.
The DCPs are imported from USB/CRU hard drives or by internet
download to the server. They are stored encrypted at all times.
The projector includes a so called "Media Block" which handles DRM
and decryption. It receives the DCP data and the KDM to decrypt each
frame in real time.
On DCP playback the Projector will send the decrypted PCM audio to
the Audio Processor which will then send each processed Audio Channel
to the respective Speakers.
DCP Disks
DCP Format
A DCP is a folder which contains XML metadata files and multiple MXF
files for the actual movie.
Folder Naming Pattern
AwesomeMovie_FTR-2_S_DE-XX_DE-16_51_4K_20240119_SMPTE_OV
* AwesomeMovie: A short version of the movie title
* FTR: Media Type, in this case "Feature"
* 2: Version Number
* S: Aspect ratio, in this case 2.35:1 aka "Sope"
* DE: Audio Language
* XX: Subtitle Language, in this case is no subtitle available
* DE: Territory
* 16: Age Rating
* 51: Audio channels, in this case 5.1 surround sound
* 4K: Movie resolution, in this case 4096x1716 pixels
* 20240119: Mastering timestamp
* SMPTE: DCP standard, there is also Interop
* OV: Package type, original version or VF for version file
Credits: http://static.kinofreund.com/dcnt/
Mastering Process
During the Mastering Process a static AES 128 bit key is generated
and the original medium is converted into MXF files. One for picture
and one for audio.
For mastering the tool DCP-o-matic can be used. There are also some
commercial products.
graph LR
movie["Source"] --> mastering{{"Movie Mastering"}}
mastering --> dcpkey["Static
AES-128 Key"]
mastering --> dcp["Digital Cinema Package (DCP)"]
dcp --> dcppics["Encrypted
Picture Data"]
dcp --> dcpsound["Encrypted
Audio Data"]
dcp --> dcpsub["Encrypted
Subtitle Data"]
The video stream is encoded as one single JPEG2000 picture per frame.
Each frame is encrypted with the same static AES key.
The audio stream is (most likely) chunked into one BWF (Broadcast
Wave Format) stream per frame and also encrypted separately. (The
author haven't found any information about this yet.)
A DCP can have a size of 200 GB or more. Some newer releases can hit
the Terabyte, if multiple versions (Languages, Subtitles, 2D/3D) are
shipped on the same harddrive.
The subtitles are provided in an XML file or are burned directly into
the picture frames. If it is provided as an XML file, the projector
will render the subtitles using a TTF font file.
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
MovieTitle
1
de
WUSTE VON NEVADA - HEUTE
Supplemental DCP (VF, Version File)
A supplemental DCP allows to reuse the Original DCP (OV, Original
File) picture and replace audio or subtitle tracks. This makes it
possible to support different languages without the need of shipping
hundreds of gigabytes of duplicated picture data to the cinemas.
graph TD
f[PaktDerWoelfe_FTR_S-235_FR-XX_DE_51_4K_SC_20230926_EGB_SMPTE_OV]
f --> a[PaktDerWoelBoC_FTR_S-235_DE-DE_DE_51_4K_SC_20231115_EGB_SMPTE_VF]
f --> b[PaktDerWoelBoC_FTR_S-235_FR-DE_DE_51_4K_SC_20231115_EGB_SMPTE_VF]
Example: One version file for German with German subtitles and one
for French with German subtitles.
It is even possible to provide differnt cuts of a movie for different
regions.
Software
Two Open Source C++ implementations, both in active development, one
from the industry!
cth103/libdcp, a C++ library written by the makers of DCP-o-matic:
* https://git.carlh.net/gitweb/?p=dcpomatic.git;a=shortlog
* https://dcpomatic.com/ (source code)
asdcplib, a C++ library written by companies active in the cinema
industry:
The asdcplib project was originally exchanged by FTP. The project
was on SourceForge between 2005 and 2008, when it moved to a
release-only distribution via CineCert. As of late February 2019,
its new home is on github.
- https://github.com/cinecert/asdcplib
Almost all software, commercial or open source is using one of these
libraries.
Distribution
The symmetric encryption key for the DCP has to be protected in some
way. For this, the producer will create a DKDM XML file, containing
the AES Key, which has been encrypted with the Certificate Public Key
of the distributor.
The distributor can then use the DKDM to create KDM XML files for
cinemas. This means decrypting the DCP AES Key and encrypting it
again with the Certificate Public Key of the target projection
system.
Certificate Chains
Both projectors and distributors use SSL certificate chains to sign
and encrypt/decrypt data.
A chain always consists of a Root Certificate Authority (CA),
Intermediate CA and a Leaf Certificate.
graph TD
a["dnQualifier=ZwVjULQy61,CN=.smpte-430-2.root,OU=movies.serverless.industries,O=serverless.industries"]
a --> b["dnQualifier=/JLF0JtscFuJahVNXfYu1w1u7SI=,CN=.smpte-430-2.intermediate,OU=movies.serverless.industries,O=serverless.industries"]
b --> c["dnQualifier=TEqiLeRuVnkbNOUsPlbDHIdp1tM=,CN=CS.smpte-430-2.leaf,OU=movies.serverless.industries,O=serverless.industries"]
The field dnQualifier in the subject is the fingerprint of the public
key of the generated certificate:
cat leaf.pem | openssl x509 -pubkey -noout | \
openssl base64 -d | dd bs=1 skip=24 2>/dev/null | \
openssl sha1 -binary | openssl base64
Script for creating a certificate chain: create-smpte-chain.sh
Key Delivery Messages
A KDM is a XML file which contains the AES key of the DCP encrypted
with the projectors Public Key.
* Various XML Schemas: SMPTE 430-1, SMPTE 430-3
* Document signing with XML-DSig
* One or more elements contain the AES keys and
some metadata for multiple DCP OV/VF, both encrypted
Decrypt the with openssl:
cat KDM_KaizoTrap_FTR-1_F_XX-XX_20_2K_20240119_SMPTE_OV_My_nonexistent_cinema_Nonexistent_Screen_1.xml | \
xq -r '.DCinemaSecurityMessage.AuthenticatedPrivate."enc:EncryptedKey"[0]."enc:CipherData"."enc:CipherValue"' | \
base64 -d | \
openssl pkeyutl -decrypt -inkey leaf.key -pkeyopt rsa_padding_mode:oaep > kdminfo.bin
Output of hexdump -C kdminfo.bin:
00000000 f1 dc 12 44 60 16 9a 0e 85 bc 30 06 42 f8 66 ab |...D`.....0.B.f.|
00000010 28 fd 80 bf a9 bb f1 dc 48 d9 87 e9 5c c9 a5 41 |(.......H...\..A|
00000020 ab 8e 14 82 88 40 c3 90 2a 0b 46 21 b4 10 49 6b |.....@..*.F!..Ik|
00000030 b8 a4 a9 4f 4d 44 41 4b 2e 2e 05 b5 bb ed 45 79 |...OMDAK......Ey|
00000040 96 cc 9c d6 00 ed db 4c 32 30 32 34 2d 30 31 2d |.......L2024-01-|
00000050 32 38 54 31 39 3a 30 30 3a 30 30 2b 30 31 3a 30 |28T19:00:00+01:0|
00000060 30 32 30 32 34 2d 30 32 2d 30 34 54 32 30 3a 30 |02024-02-04T20:0|
00000070 30 3a 30 30 2b 30 31 3a 30 30 4c 3a b6 ed 71 eb |0:00+01:00L:..q.|
00000080 29 25 90 48 6b 4f 96 2f 44 f6 |)%.HkO./D.|
0000008a
The file can now be sliced into single fields with dd:
# fingerprint base64 encoded
dd if=kdminfo.bin bs=1 skip=16 count=20 status=none | base64
# AES key in hexadecimal
dd if=kdminfo.bin bs=1 skip=122 count=16 status=none | hexdump -C
# date string in plain text ASCII
dd if=kdminfo.bin bs=1 skip=97 count=25 status=none; echo
Format:
Start Length Description
0 16 Structure ID, binary, static
0xf1dc124460169a0e85bc300642f866ab
16 20 Signer certificate fingerprint, binary,
KP2Av6m78dxI2YfpXMmlQauOFII=
36 16 Composition Playlist UUID,
8840c390-2a0b-4621-b410-496bb8a4a94f
52 4 Key Type, ASCII, MDAK = Main Sound
56 16 Key UUID, 2e2e05b5-bbed-4579-96cc-9cd600eddb4c
72 25 Not valid before date string, ASCII,
2024-01-28T19:00:00+01:00
97 25 Not valid after date string, ASCII,
2024-02-04T20:00:00+01:00
122 16 AES decryption key, binary,
0x4c3ab6ed71eb292590486b4f962f44f6
* Validate signer certificate: Should match the fingerprint of the
leaf certificate used to sign the KDM XML structure
openssl asn1parse -in leaf.pem -noout -strparse 4 -out - | \
openssl dgst -sha1 -binary | \
openssl base64
* Validate Composition Playlist UUID: Should appear in the KDM XML
field
* Validate Key UUID: Should appear in the KDM XML field
* Validate Key Type: Should match the type for the respective Key
UUID block
* Validate Dates: Should appear in the KDM XML fields
and
(This is a subset of checks documented in the DCI Compliance Test
Plan)
The projector itself has no trusted CA store for validating KDMs or
DCPs. The whole process relies on the fingerprint stored in the
and that the recipient cinema has no access to the
Projectors Private Key.
Trusted Device List
Could one just build their own DCI/DCP projector?
Yes and no.
The software exists, in theory just a Linux PC and any projector /
sound system is required.
The distributors use a so called "Trusted Device List" provided by
the DCI certified projection system manufacturers. Projectors which
are not mentioned on these lists will not get a DCP/KDM from many
distributors.
Also a DCI certified projection system must be installed by an
authorized company.
* KDM Request by Serial Number: Many distributors just ask for
projector model and serial number. They can query the actual
projection system certificate in their distribution system
* KDM Request by Certificate: The cinema has to provide their
projector certificate which is then validated against the
projection systems manufacturer root certificate
If a cinema is not "playing by the rules", a 30k+ EUR projection
system will become an expensive brick.
MXF File Format
MXF is used by the whole movie and broadcasting industry.
The paper of the SMPTE standard is again purchase-only.
Since the standard is quite complex, the Author used MXFInspect as a
shortcut and only parsed a single Frame / Triplet.
BER Encoding
Basic Encoding Rules:
* BER is indicated if the first bit of the byte is a 1
* Bits 2-8 contain the number of bytes used for the length
* The length bytes contain the length of the data
BER Indicator Length Content
0x83 = 10000011b 0x004F0C 20236 bytes of data
= 3 bytes for length = 20236d
Triplet Format (Single Movie Frame)
Frame Triplet Structure
Start Type Length Description
0 DAT 16 Encrypted triplet key
16 BER 1 BER 0x83 = 10000011b = Next field is 3 bytes long
17 LEN 3 0x004F0C = 20236d = Length of the data
20 BER 1 BER 0x83 = 10000011b = Next field is 3 bytes long
21 LEN 3 0x000010 = 16d = Length of the next field
24 DAT 16 Cryptographic Context Link
40 BER 1 BER 0x83 = 10000011b = Next field is 3 bytes long
41 LEN 3 0x000008 = 8d = Length of the next field
44 DAT 8 Plaintext offset
52 BER 1 BER 0x83 = 10000011b = Next field is 3 bytes long
53 LEN 3 0x000010 = 16d = Length of the next field
56 DAT 16 Source Key
72 BER 1 BER 0x83 = 10000011b = Next field is 3 bytes long
73 LEN 3 0x000008 = 8d = Length of the next field
76 DAT 8 Source Length
84 BER 1 BER 0x83 = 10000011b = Next field is 3 bytes long
85 LEN 3 0x004e90 = 20112d = Length of the next field
88 DAT 20112 Encrypted Source Value
Slice the data
# slice the first frame from the MXF bodypartition
# offsets from MXFInspect
dd if=file.mxf bs=1 count=20256 skip=16524 of=block.bin
# slice data from the frame
dd if=block.bin skip=88 count=20112 bs=1 of=block-encrypted-data.bin
Decrypt Frame Data
The DCP encryption key: 4c3ab6ed71eb292590486b4f962f44f6
The frame IV
Every Frame is using a unique IV (Initialization Vector), which
ensures that the AES Block Cipher generates always different cipher
texts and makes brute force harder. This works similar to a Password
Salt.
# the data starts with 16 bytes of iv and 16 bytes of cv
# AES iv bytes
dd if=block-encrypted-data.bin bs=1 count=16 of=iv.bin
Output of hexdump -C iv.bin:
00000000 16 6e 7b d1 67 81 44 2e 7a ca de 3c 46 cc d7 39 |.n{.g.D.z.. block-decrypted-data.bin
MXFs created by DCP-o-Matic contain libdcp in the hexdump, which
indicates that the decryption was successful.
Output of hexdump -C block-decrypted-data.bin | head:
00000000 3a f0 b7 f5 53 49 eb b7 c0 c0 cb a5 c9 2f 35 19 |:...SI......./5.|
00000010 00 00 00 00 00 00 00 00 00 00 07 ce 00 00 04 38 |...............8|
00000020 00 00 00 00 00 00 00 00 00 03 0b 01 01 0b 01 01 |................|
00000030 0b 01 01 ff 52 00 12 01 04 00 01 01 05 03 03 00 |....R...........|
00000040 00 77 88 88 88 88 88 ff 5c 00 23 22 97 20 96 f0 |.w......\.#". ..|
00000050 96 f0 96 c0 8f 00 8f 00 8e e0 87 50 87 50 87 68 |...........P.P.h|
00000060 70 05 70 05 70 47 77 d3 77 d3 77 62 ff 55 00 13 |p.p.pGw.w.wb.U..|
00000070 00 50 00 00 00 4d 40 00 00 00 00 49 00 00 00 00 |.P...M@....I....|
00000080 49 ff 64 00 0a 00 01 6c 69 62 64 63 70 ff 90 00 |I.d....libdcp...|
00000090 0a 00 00 00 00 4d 40 00 03 ff 93 ef fe 2c 71 ff |.....M@......,q.|
Magic Signatures
At first, the decrypted Frame could not be opened in GIMP.
To enable programs to open a file in the correct way, many files
contain so called "Magic Signatures" at its beginning.
This magic value in block-decrypted-data.bin is incorrect for unknown
reasons. When extracting a JPEG2000 frame from an unencrypted MXF,
the signature is correct. As a simple hack, the author just copied
the signature from the unencrypted MXF frame to the decrypted one:
# offset again from MXFInspect
dd if=j2c_caa6b39e-bd57-4676-9797-112e96a6f0c3.mxf bs=1 skip=16524 count=20085 of=frame.bin
# unencrypted frame does not contain crypto info
# so we just have to slice the first BER header
dd if=framedata.bin.j2k bs=1 skip=20 count=16 of=j2k_header.bin
# now back to the decrypted mxf frame
# replace signature
cp j2k_header.bin frame.j2k
dd if=block-decrypted-data.bin bs=1 skip=16 >> image.j2k
It should now be possible to open the file in GIMP. GIMP will show
the frame with wrong colors, as MXF files use a custom color space.
Movie Screenshot with wrong color space
The original Frame with correct colors:
Movie Screenshot with correct colors
Credit: Kaizo Trap by Guy Collins Animation
Why it's safe
Everything relies on "never reusing AES Keys" and "protected private
keys".
* KDM data is encrypted with a 2048 bit RSA key
* MXF data is encrypted with AES-128
* Decryption keys are always stored in TPM-like hardware
* Every DCP uses unique encryption keys
* Every projector uses unique certificates/keys
* A DCI certified projector is required
* Distributors can verify if a certificate belongs to a certified
DCI projector
How it's going
DCI has released version 1.4.4 of the specification, which now allows
playback of DCPs with expired signer certificate.
The manufacturers already started to work on a software update.
Sources
* DCI Specification
* DCI Compliance Test Plan
* OpenSSL Foo
* Key Types
* DC Tools by WolfgangW
* MXFInspect
* MXF Triplets
* SMPTE Standard
* MXF Triplet Encryption
* Showing jpeg2000 in Gimp / parsing jpeg2000 data from mxf
* List of magic signatures
Credits
Thanks for reading and feedback goes to: Pliskin, babel
---------------------------------------------------------------------
More
* Never use RegExp as a parser
* DNS Updates with nsupdate
* Blinkenlights over Serial
* Implementing a WebDAV Client in .NET
* Building a smart door bell
---------------------------------------------------------------------
go back
make offline copy delete offline copy Creative Commons License
serverless.industries BG by Carl Lender (CC BY 2.0) Imprint & Privacy
97aa53c1 2025-04-20 19:49
Back to top
Mastodon via chaos.social Mastodon via einbeck.social