[vlc-devel] [RFC] VLC and CSA encryption/decryption
Georgi Chorbadzhiyski
gf at unixsol.org
Fri Apr 6 12:08:12 CEST 2012
I was adding support for constant code word decryption in tsdecrypt [1] and tried
to test it using VLC [2] to encrypt an audio stream (video was left not encrypted).
I was very surprised to see that the decryption was not working. When i started
digging it turns out that CSA encrypted stream with VLC, can not be decoded by
libdvbcsa.
I thought it was a problem with key setup in the VLC code (modules/mux/mpeg/csa.c)
and to confirm my suspicion I patched csa.c to use libdvbcsa. With the attached patch
the decryption with tsdecrypt started working.
This poses a problem. Currently CSA encrypted streams with VLC can be decoded with
VLC but not libdvbcsa (i suspect decryption will have the same problem VLC<->VLC - works,
libdvbcsa<->VLC - don't work). But if VLC is patched to use libdvbcsa (or fixed to
setup the CSA key like libdvbcsa), older VLC versions will not be able to decrypt
the streams.
I don't know what the correct solution is.
Anyway the attached patch is just a quick hack (no configure support, current csa
code is just commented out) but it works in the sense that libdvbcsa is able to
decrypt VLC generated CSA encrypted stream.
What I have tested:
Run vlc to encrypt audio stream (reads from 239.1.1.1:4000 outputs to 239.1.1.1:5000):
vlc \
-I dummy -v \
--sout '#standard{access=udp,mux=ts,dst=239.1.1.1:5000}' \
--no-sout-ts-crypt-video \
--sout-ts-crypt-audio \
--sout-ts-csa-ck=1234567890123456 \
--sout-ts-csa2-ck=abcdefabcdefabcd \
udp://@239.1.1.1:4000/
Install tsdecrypt:
git clone git://github.com/gfto/tsdecrypt.git
cd tsdecrypt
git submodule init
git submodule update
make
and run it (reads from 239.1.1.1:5000 outputs to 239.1.1.1:6000):
./tsdecrypt --input 239.1.1.1:5000 --output 239.1.1.1:6000 --const-cw 1234567890123456abcdefabcdefabcd
You should be able to open udp://@239.1.1.1:6000/ and watch and listen to the
audio stream in case the VLC is patched or view only the video in case VLC is
not patched.
[1]: https://github.com/gfto/tsdecrypt
[2]: VLC version 2.1.0-git Rincewind (1.3.0-git-2035-g2f35b87)
--
Georgi Chorbadzhiyski
http://georgi.unixsol.org/
-------------- next part --------------
From 8da11b38907062cc4a718f0b72e53629931d6f40 Mon Sep 17 00:00:00 2001
From: Georgi Chorbadzhiyski <gf at unixsol.org>
Date: Fri, 6 Apr 2012 12:42:49 +0300
Subject: [PATCH] Use libdvbcsa for csa encryption and decryption.
---
modules/mux/Modules.am | 2 +-
modules/mux/mpeg/csa.c | 29 ++++++++++++++++++++++++++++-
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/modules/mux/Modules.am b/modules/mux/Modules.am
index b166cf3..c75a86f 100644
--- a/modules/mux/Modules.am
+++ b/modules/mux/Modules.am
@@ -21,7 +21,7 @@ libmux_ts_plugin_la_SOURCES = \
mpeg/csa.c mpeg/csa.h \
mpeg/ts.c mpeg/bits.h
libmux_ts_plugin_la_CFLAGS = $(AM_CFLAGS) $(DVBPSI_CFLAGS)
-libmux_ts_plugin_la_LIBADD = $(AM_LIBADD) $(DVBPSI_LIBS)
+libmux_ts_plugin_la_LIBADD = $(AM_LIBADD) $(DVBPSI_LIBS) -ldvbcsa
libmux_ts_plugin_la_DEPENDENCIES =
if HAVE_DVBPSI
libvlc_LTLIBRARIES += libmux_ts_plugin.la
diff --git a/modules/mux/mpeg/csa.c b/modules/mux/mpeg/csa.c
index b1381a8..29e8399 100644
--- a/modules/mux/mpeg/csa.c
+++ b/modules/mux/mpeg/csa.c
@@ -26,6 +26,8 @@
# include "config.h"
#endif
+#include <dvbcsa/dvbcsa.h>
+
#include <vlc_common.h>
#include "csa.h"
@@ -36,6 +38,9 @@ struct csa_t
uint8_t o_ck[8];
uint8_t e_ck[8];
+ struct dvbcsa_key_s *dcsa_o;
+ struct dvbcsa_key_s *dcsa_e;
+
uint8_t o_kk[57];
uint8_t e_kk[57];
@@ -61,7 +66,12 @@ static void csa_BlockCypher( uint8_t kk[57], uint8_t bd[8], uint8_t ib[8] );
*****************************************************************************/
csa_t *csa_New( void )
{
- return calloc( 1, sizeof( csa_t ) );
+ csa_t *csa = calloc( 1, sizeof( csa_t ) );
+ if ( csa ) {
+ csa->dcsa_o = dvbcsa_key_alloc();
+ csa->dcsa_e = dvbcsa_key_alloc();
+ }
+ return csa;
}
/*****************************************************************************
@@ -69,6 +79,9 @@ csa_t *csa_New( void )
*****************************************************************************/
void csa_Delete( csa_t *c )
{
+ dvbcsa_key_free( c->dcsa_o );
+ dvbcsa_key_free( c->dcsa_e );
+
free( c );
}
@@ -111,11 +124,13 @@ int csa_SetCW( vlc_object_t *p_caller, csa_t *c, char *psz_ck, bool set_odd )
{
memcpy( c->o_ck, ck, 8 );
csa_ComputeKey( c->o_kk, ck );
+ dvbcsa_key_set( c->o_ck, c->dcsa_o );
}
else
{
memcpy( c->e_ck , ck, 8 );
csa_ComputeKey( c->e_kk , ck );
+ dvbcsa_key_set( c->e_ck, c->dcsa_e );
}
return VLC_SUCCESS;
}
@@ -142,6 +157,7 @@ void csa_Decrypt( csa_t *c, uint8_t *pkt, int i_pkt_size )
{
uint8_t *ck;
uint8_t *kk;
+ struct dvbcsa_key_s *dcsa;
uint8_t ib[8], stream[8], block[8];
@@ -158,11 +174,13 @@ void csa_Decrypt( csa_t *c, uint8_t *pkt, int i_pkt_size )
{
ck = c->o_ck;
kk = c->o_kk;
+ dcsa = c->dcsa_o;
}
else
{
ck = c->e_ck;
kk = c->e_kk;
+ dcsa = c->dcsa_e;
}
/* clear transport scrambling control */
@@ -178,6 +196,9 @@ void csa_Decrypt( csa_t *c, uint8_t *pkt, int i_pkt_size )
if( 188 - i_hdr < 8 )
return;
+ dvbcsa_decrypt(dcsa, &pkt[i_hdr], 188 - i_hdr);
+ return;
+
/* init csa state */
csa_StreamCypher( c, 1, ck, &pkt[i_hdr], ib );
@@ -231,6 +252,7 @@ void csa_Encrypt( csa_t *c, uint8_t *pkt, int i_pkt_size )
{
uint8_t *ck;
uint8_t *kk;
+ struct dvbcsa_key_s *dcsa;
int i, j;
int i_hdr = 4; /* hdr len */
@@ -245,11 +267,13 @@ void csa_Encrypt( csa_t *c, uint8_t *pkt, int i_pkt_size )
pkt[3] |= 0x40;
ck = c->o_ck;
kk = c->o_kk;
+ dcsa = c->dcsa_o;
}
else
{
ck = c->e_ck;
kk = c->e_kk;
+ dcsa = c->dcsa_e;
}
/* hdr len */
@@ -268,6 +292,9 @@ void csa_Encrypt( csa_t *c, uint8_t *pkt, int i_pkt_size )
return;
}
+ dvbcsa_encrypt(dcsa, &pkt[i_hdr], 188 - i_hdr);
+ return;
+
/* */
for( i = 0; i < 8; i++ )
{
--
1.7.5.1
More information about the vlc-devel
mailing list