Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
34acedc6
Commit
34acedc6
authored
Mar 26, 2012
by
Frédéric Yhuel
Committed by
Jean-Baptiste Kempf
Mar 26, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
demux/mp4: drop DRMS support
Signed-off-by:
Jean-Baptiste Kempf
<
jb@videolan.org
>
parent
790d3d45
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
11 additions
and
2276 deletions
+11
-2276
modules/demux/mkv/Modules.am
modules/demux/mkv/Modules.am
+1
-1
modules/demux/mp4/Modules.am
modules/demux/mp4/Modules.am
+0
-3
modules/demux/mp4/drms.c
modules/demux/mp4/drms.c
+0
-1809
modules/demux/mp4/drms.h
modules/demux/mp4/drms.h
+0
-35
modules/demux/mp4/drmstables.h
modules/demux/mp4/drmstables.h
+0
-299
modules/demux/mp4/libmp4.c
modules/demux/mp4/libmp4.c
+9
-81
modules/demux/mp4/libmp4.h
modules/demux/mp4/libmp4.h
+0
-4
modules/demux/mp4/mp4.c
modules/demux/mp4/mp4.c
+1
-44
No files found.
modules/demux/mkv/Modules.am
View file @
34acedc6
...
...
@@ -7,6 +7,6 @@ SOURCES_mkv = mkv.hpp mkv.cpp \
chapters.hpp chapters.cpp \
chapter_command.hpp chapter_command.cpp \
stream_io_callback.hpp stream_io_callback.cpp \
../mp4/libmp4.c
../mp4/drms.c
\
../mp4/libmp4.c \
../vobsub.h
modules/demux/mp4/Modules.am
View file @
34acedc6
...
...
@@ -2,9 +2,6 @@ SOURCES_mp4 = \
mp4.c \
libmp4.c \
libmp4.h \
drms.c \
drms.h \
drmstables.h \
id3genres.h \
$(NULL)
...
...
modules/demux/mp4/drms.c
deleted
100644 → 0
View file @
790d3d45
/*****************************************************************************
* drms.c: DRMS
*****************************************************************************
* Copyright (C) 2004 the VideoLAN team
* $Id$
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Sam Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
/* In Solaris (and perhaps others) PATH_MAX is in limits.h. */
#include <limits.h>
#ifdef WIN32
# include <io.h>
# if !defined( UNDER_CE )
# include <direct.h>
# endif
# include <tchar.h>
# include <shlobj.h>
# include <windows.h>
#else
# include <stdio.h>
#endif
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <vlc_common.h>
#include <vlc_md5.h>
#include "libmp4.h"
#include <vlc_fs.h>
#ifdef __APPLE__
#include "TargetConditionals.h"
#ifndef TARGET_OS_IPHONE
#define HAVE_MACOS_IOKIT
#endif
#endif
#ifdef HAVE_MACOS_IOKIT
# include <mach/mach.h>
# include <IOKit/IOKitLib.h>
# include <CoreFoundation/CFNumber.h>
#endif
#include "drms.h"
#include "drmstables.h"
#if !defined( UNDER_CE )
/*****************************************************************************
* aes_s: AES keys structure
*****************************************************************************
* This structure stores a set of keys usable for encryption and decryption
* with the AES/Rijndael algorithm.
*****************************************************************************/
struct
aes_s
{
uint32_t
pp_enc_keys
[
AES_KEY_COUNT
+
1
][
4
];
uint32_t
pp_dec_keys
[
AES_KEY_COUNT
+
1
][
4
];
};
#define Digest DigestMD5
/*****************************************************************************
* shuffle_s: shuffle structure
*****************************************************************************
* This structure stores the static information needed to shuffle data using
* a custom algorithm.
*****************************************************************************/
struct
shuffle_s
{
uint32_t
i_version
;
uint32_t
p_commands
[
20
];
uint32_t
p_bordel
[
16
];
};
#define SWAP( a, b ) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
/*****************************************************************************
* drms_s: DRMS structure
*****************************************************************************
* This structure stores the static information needed to decrypt DRMS data.
*****************************************************************************/
struct
drms_s
{
uint32_t
i_user
;
uint32_t
i_key
;
uint8_t
p_iviv
[
16
];
uint8_t
*
p_name
;
uint32_t
p_key
[
4
];
struct
aes_s
aes
;
char
psz_homedir
[
PATH_MAX
];
};
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
void
InitAES
(
struct
aes_s
*
,
uint32_t
*
);
static
void
DecryptAES
(
struct
aes_s
*
,
uint32_t
*
,
const
uint32_t
*
);
static
void
InitShuffle
(
struct
shuffle_s
*
,
uint32_t
*
,
uint32_t
);
static
void
DoShuffle
(
struct
shuffle_s
*
,
uint32_t
*
,
uint32_t
);
static
uint32_t
FirstPass
(
uint32_t
*
);
static
void
SecondPass
(
uint32_t
*
,
uint32_t
);
static
void
ThirdPass
(
uint32_t
*
);
static
void
FourthPass
(
uint32_t
*
);
static
void
TinyShuffle1
(
uint32_t
*
);
static
void
TinyShuffle2
(
uint32_t
*
);
static
void
TinyShuffle3
(
uint32_t
*
);
static
void
TinyShuffle4
(
uint32_t
*
);
static
void
TinyShuffle5
(
uint32_t
*
);
static
void
TinyShuffle6
(
uint32_t
*
);
static
void
TinyShuffle7
(
uint32_t
*
);
static
void
TinyShuffle8
(
uint32_t
*
);
static
void
DoExtShuffle
(
uint32_t
*
);
static
int
GetSystemKey
(
uint32_t
*
,
bool
);
static
int
WriteUserKey
(
void
*
,
uint32_t
*
);
static
int
ReadUserKey
(
void
*
,
uint32_t
*
);
static
int
GetUserKey
(
void
*
,
uint32_t
*
);
static
int
GetSCIData
(
char
*
,
uint32_t
**
,
uint32_t
*
);
static
int
HashSystemInfo
(
uint32_t
*
);
static
int
GetiPodID
(
int64_t
*
);
#ifdef WORDS_BIGENDIAN
/*****************************************************************************
* Reverse: reverse byte order
*****************************************************************************/
static
inline
void
Reverse
(
uint32_t
*
p_buffer
,
int
n
)
{
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
p_buffer
[
i
]
=
GetDWLE
(
&
p_buffer
[
i
]);
}
}
# define REVERSE( p, n ) Reverse( p, n )
#else
# define REVERSE( p, n )
#endif
/*****************************************************************************
* BlockXOR: XOR two 128 bit blocks
*****************************************************************************/
static
inline
void
BlockXOR
(
uint32_t
*
p_dest
,
uint32_t
*
p_s1
,
uint32_t
*
p_s2
)
{
int
i
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
p_dest
[
i
]
=
p_s1
[
i
]
^
p_s2
[
i
];
}
}
/*****************************************************************************
* drms_alloc: allocate a DRMS structure
*****************************************************************************/
void
*
drms_alloc
(
const
char
*
psz_homedir
)
{
struct
drms_s
*
p_drms
;
p_drms
=
calloc
(
1
,
sizeof
(
struct
drms_s
)
);
if
(
!
p_drms
)
return
NULL
;
strncpy
(
p_drms
->
psz_homedir
,
psz_homedir
,
PATH_MAX
);
p_drms
->
psz_homedir
[
PATH_MAX
-
1
]
=
'\0'
;
return
(
void
*
)
p_drms
;
}
/*****************************************************************************
* drms_free: free a previously allocated DRMS structure
*****************************************************************************/
void
drms_free
(
void
*
_p_drms
)
{
struct
drms_s
*
p_drms
=
(
struct
drms_s
*
)
_p_drms
;
free
(
(
void
*
)
p_drms
->
p_name
);
free
(
p_drms
);
}
/*****************************************************************************
* drms_decrypt: unscramble a chunk of data
*****************************************************************************/
void
drms_decrypt
(
void
*
_p_drms
,
uint32_t
*
p_buffer
,
uint32_t
i_bytes
,
uint32_t
*
p_key
)
{
struct
drms_s
*
p_drms
=
(
struct
drms_s
*
)
_p_drms
;
uint32_t
p_key_buf
[
4
];
unsigned
int
i_blocks
;
/* AES is a block cypher, round down the byte count */
i_blocks
=
i_bytes
/
16
;
i_bytes
=
i_blocks
*
16
;
/* Initialise the key */
if
(
!
p_key
)
{
p_key
=
p_key_buf
;
memcpy
(
p_key
,
p_drms
->
p_key
,
16
);
}
/* Unscramble */
while
(
i_blocks
--
)
{
uint32_t
p_tmp
[
4
];
REVERSE
(
p_buffer
,
4
);
DecryptAES
(
&
p_drms
->
aes
,
p_tmp
,
p_buffer
);
BlockXOR
(
p_tmp
,
p_key
,
p_tmp
);
/* Use the previous scrambled data as the key for next block */
memcpy
(
p_key
,
p_buffer
,
16
);
/* Copy unscrambled data back to the buffer */
memcpy
(
p_buffer
,
p_tmp
,
16
);
REVERSE
(
p_buffer
,
4
);
p_buffer
+=
4
;
}
}
/*****************************************************************************
* drms_get_p_key: copy the p_key into user buffer
****************************************************************************/
void
drms_get_p_key
(
void
*
_p_drms
,
uint32_t
*
p_key
)
{
struct
drms_s
*
p_drms
=
(
struct
drms_s
*
)
_p_drms
;
memcpy
(
p_key
,
p_drms
->
p_key
,
16
);
}
/*****************************************************************************
* drms_init: initialise a DRMS structure
*****************************************************************************
* Return values:
* 0: success
* -1: unimplemented
* -2: invalid argument
* -3: could not get system key
* -4: could not get SCI data
* -5: no user key found in SCI data
* -6: invalid user key
*****************************************************************************/
int
drms_init
(
void
*
_p_drms
,
uint32_t
i_type
,
uint8_t
*
p_info
,
uint32_t
i_len
)
{
struct
drms_s
*
p_drms
=
(
struct
drms_s
*
)
_p_drms
;
int
i_ret
=
0
;
switch
(
i_type
)
{
case
ATOM_user
:
if
(
i_len
<
sizeof
(
p_drms
->
i_user
)
)
{
i_ret
=
-
2
;
break
;
}
p_drms
->
i_user
=
U32_AT
(
p_info
);
break
;
case
ATOM_key
:
if
(
i_len
<
sizeof
(
p_drms
->
i_key
)
)
{
i_ret
=
-
2
;
break
;
}
p_drms
->
i_key
=
U32_AT
(
p_info
);
break
;
case
ATOM_iviv
:
if
(
i_len
<
sizeof
(
p_drms
->
p_key
)
)
{
i_ret
=
-
2
;
break
;
}
memcpy
(
p_drms
->
p_iviv
,
p_info
,
16
);
break
;
case
ATOM_name
:
p_drms
->
p_name
=
(
uint8_t
*
)
strdup
(
(
char
*
)
p_info
);
if
(
p_drms
->
p_name
==
NULL
)
{
i_ret
=
-
2
;
}
break
;
case
ATOM_priv
:
{
uint32_t
p_priv
[
64
];
struct
md5_s
md5
;
if
(
i_len
<
64
||
p_drms
->
p_name
==
NULL
)
{
i_ret
=
-
2
;
break
;
}
InitMD5
(
&
md5
);
AddMD5
(
&
md5
,
p_drms
->
p_name
,
strlen
(
(
char
*
)
p_drms
->
p_name
)
);
AddMD5
(
&
md5
,
p_drms
->
p_iviv
,
16
);
EndMD5
(
&
md5
);
if
(
p_drms
->
i_user
==
0
&&
p_drms
->
i_key
==
0
)
{
static
const
char
p_secret
[]
=
"tr1-th3n.y00_by3"
;
memcpy
(
p_drms
->
p_key
,
p_secret
,
16
);
REVERSE
(
p_drms
->
p_key
,
4
);
}
else
{
i_ret
=
GetUserKey
(
p_drms
,
p_drms
->
p_key
);
if
(
i_ret
)
{
break
;
}
}
InitAES
(
&
p_drms
->
aes
,
p_drms
->
p_key
);
memcpy
(
p_priv
,
p_info
,
64
);
memcpy
(
p_drms
->
p_key
,
md5
.
buf
,
16
);
drms_decrypt
(
p_drms
,
p_priv
,
64
,
NULL
);
REVERSE
(
p_priv
,
64
);
if
(
p_priv
[
0
]
!=
0x6e757469
)
/* itun */
{
i_ret
=
-
6
;
break
;
}
InitAES
(
&
p_drms
->
aes
,
p_priv
+
6
);
memcpy
(
p_drms
->
p_key
,
p_priv
+
12
,
16
);
free
(
(
void
*
)
p_drms
->
p_name
);
p_drms
->
p_name
=
NULL
;
}
break
;
}
return
i_ret
;
}
/* The following functions are local */
/*****************************************************************************
* InitAES: initialise AES/Rijndael encryption/decryption tables
*****************************************************************************
* The Advanced Encryption Standard (AES) is described in RFC 3268
*****************************************************************************/
static
void
InitAES
(
struct
aes_s
*
p_aes
,
uint32_t
*
p_key
)
{
unsigned
int
i
,
t
;
uint32_t
i_key
,
i_seed
;
memset
(
p_aes
->
pp_enc_keys
[
1
],
0
,
16
);
memcpy
(
p_aes
->
pp_enc_keys
[
0
],
p_key
,
16
);
/* Generate the key tables */
i_seed
=
p_aes
->
pp_enc_keys
[
0
][
3
];
for
(
i_key
=
0
;
i_key
<
AES_KEY_COUNT
;
i_key
++
)
{
uint32_t
j
;
i_seed
=
AES_ROR
(
i_seed
,
8
);
j
=
p_aes_table
[
i_key
];
j
^=
p_aes_encrypt
[
(
i_seed
>>
24
)
&
0xff
]
^
AES_ROR
(
p_aes_encrypt
[
(
i_seed
>>
16
)
&
0xff
],
8
)
^
AES_ROR
(
p_aes_encrypt
[
(
i_seed
>>
8
)
&
0xff
],
16
)
^
AES_ROR
(
p_aes_encrypt
[
i_seed
&
0xff
],
24
);
j
^=
p_aes
->
pp_enc_keys
[
i_key
][
0
];
p_aes
->
pp_enc_keys
[
i_key
+
1
][
0
]
=
j
;
j
^=
p_aes
->
pp_enc_keys
[
i_key
][
1
];
p_aes
->
pp_enc_keys
[
i_key
+
1
][
1
]
=
j
;
j
^=
p_aes
->
pp_enc_keys
[
i_key
][
2
];
p_aes
->
pp_enc_keys
[
i_key
+
1
][
2
]
=
j
;
j
^=
p_aes
->
pp_enc_keys
[
i_key
][
3
];
p_aes
->
pp_enc_keys
[
i_key
+
1
][
3
]
=
j
;
i_seed
=
j
;
}
memcpy
(
p_aes
->
pp_dec_keys
[
0
],
p_aes
->
pp_enc_keys
[
0
],
16
);
for
(
i
=
1
;
i
<
AES_KEY_COUNT
;
i
++
)
{
for
(
t
=
0
;
t
<
4
;
t
++
)
{
uint32_t
j
,
k
,
l
,
m
,
n
;
j
=
p_aes
->
pp_enc_keys
[
i
][
t
];
k
=
(((
j
>>
7
)
&
0x01010101
)
*
27
)
^
((
j
&
0xff7f7f7f
)
<<
1
);
l
=
(((
k
>>
7
)
&
0x01010101
)
*
27
)
^
((
k
&
0xff7f7f7f
)
<<
1
);
m
=
(((
l
>>
7
)
&
0x01010101
)
*
27
)
^
((
l
&
0xff7f7f7f
)
<<
1
);
j
^=
m
;
n
=
AES_ROR
(
l
^
j
,
16
)
^
AES_ROR
(
k
^
j
,
8
)
^
AES_ROR
(
j
,
24
);
p_aes
->
pp_dec_keys
[
i
][
t
]
=
k
^
l
^
m
^
n
;
}
}
}
/*****************************************************************************
* DecryptAES: decrypt an AES/Rijndael 128 bit block
*****************************************************************************/
static
void
DecryptAES
(
struct
aes_s
*
p_aes
,
uint32_t
*
p_dest
,
const
uint32_t
*
p_src
)
{
uint32_t
p_wtxt
[
4
];
/* Working cyphertext */
uint32_t
p_tmp
[
4
];
unsigned
int
i_round
,
t
;
for
(
t
=
0
;
t
<
4
;
t
++
)
{
/* FIXME: are there any endianness issues here? */
p_wtxt
[
t
]
=
p_src
[
t
]
^
p_aes
->
pp_enc_keys
[
AES_KEY_COUNT
][
t
];
}
/* Rounds 0 - 8 */
for
(
i_round
=
0
;
i_round
<
(
AES_KEY_COUNT
-
1
);
i_round
++
)
{
for
(
t
=
0
;
t
<
4
;
t
++
)
{
p_tmp
[
t
]
=
AES_XOR_ROR
(
p_aes_itable
,
p_wtxt
);
}
for
(
t
=
0
;
t
<
4
;
t
++
)
{
p_wtxt
[
t
]
=
p_tmp
[
t
]
^
p_aes
->
pp_dec_keys
[
(
AES_KEY_COUNT
-
1
)
-
i_round
][
t
];
}
}
/* Final round (9) */
for
(
t
=
0
;
t
<
4
;
t
++
)
{
p_dest
[
t
]
=
AES_XOR_ROR
(
p_aes_decrypt
,
p_wtxt
);
p_dest
[
t
]
^=
p_aes
->
pp_dec_keys
[
0
][
t
];
}
}
/*****************************************************************************
* InitShuffle: initialise a shuffle structure
*****************************************************************************
* This function initialises tables in the p_shuffle structure that will be
* used later by DoShuffle. The only external parameter is p_sys_key.
*****************************************************************************/
static
void
InitShuffle
(
struct
shuffle_s
*
p_shuffle
,
uint32_t
*
p_sys_key
,
uint32_t
i_version
)
{
char
p_secret1
[]
=
"Tv!*"
;
static
const
char
p_secret2
[]
=
"____v8rhvsaAvOKM____FfUH%798=[;."
"____f8677680a634____ba87fnOIf)(*"
;
unsigned
int
i
;
p_shuffle
->
i_version
=
i_version
;
/* Fill p_commands using the key and a secret seed */
for
(
i
=
0
;
i
<
20
;
i
++
)
{
struct
md5_s
md5
;
int32_t
i_hash
;
InitMD5
(
&
md5
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_sys_key
,
16
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_secret1
,
4
);
EndMD5
(
&
md5
);
p_secret1
[
3
]
++
;
REVERSE
(
(
void
*
)
md5
.
buf
,
1
);
/* FIXME */
i_hash
=
((
int32_t
)
U32_AT
(
md5
.
buf
))
%
1024
;
p_shuffle
->
p_commands
[
i
]
=
i_hash
<
0
?
i_hash
*
-
1
:
i_hash
;
}
/* Fill p_bordel with completely meaningless initial values. */
memcpy
(
p_shuffle
->
p_bordel
,
p_secret2
,
64
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
p_shuffle
->
p_bordel
[
4
*
i
]
=
U32_AT
(
p_sys_key
+
i
);
REVERSE
(
p_shuffle
->
p_bordel
+
4
*
i
+
1
,
3
);
}
}
/*****************************************************************************
* DoShuffle: shuffle buffer
*****************************************************************************
* This is so ugly and uses so many MD5 checksums that it is most certainly
* one-way, though why it needs to be so complicated is beyond me.
*****************************************************************************/
static
void
DoShuffle
(
struct
shuffle_s
*
p_shuffle
,
uint32_t
*
p_buffer
,
uint32_t
i_size
)
{
struct
md5_s
md5
;
uint32_t
p_big_bordel
[
16
];
uint32_t
*
p_bordel
=
p_shuffle
->
p_bordel
;
unsigned
int
i
;
static
const
uint32_t
p_secret3
[]
=
{
0xAAAAAAAA
,
0x01757700
,
0x00554580
,
0x01724500
,
0x00424580
,
0x01427700
,
0x00000080
,
0xC1D59D01
,
0x80144981
,
0x815C8901
,
0x80544981
,
0x81D45D01
,
0x00000080
,
0x81A3BB03
,
0x00A2AA82
,
0x01A3BB03
,
0x0022A282
,
0x813BA202
,
0x00000080
,
0x6D575737
,
0x4A5275A5
,
0x6D525725
,
0x4A5254A5
,
0x6B725437
,
0x00000080
,
0xD5DDB938
,
0x5455A092
,
0x5D95A013
,
0x4415A192
,
0xC5DD393A
,
0x00000080
,
0x55555555
};
static
const
uint32_t
i_secret3
=
sizeof
(
p_secret3
)
/
sizeof
(
p_secret3
[
0
]);
static
const
char
p_secret4
[]
=
"pbclevtug (p) Nccyr Pbzchgre, Vap. Nyy Evtugf Erfreirq."
;
static
const
uint32_t
i_secret4
=
sizeof
(
p_secret4
)
/
sizeof
(
p_secret4
[
0
]);
/* It include the terminal '\0' */
/* Using the MD5 hash of a memory block is probably not one-way enough
* for the iTunes people. This function randomises p_bordel depending on
* the values in p_commands to make things even more messy in p_bordel. */
for
(
i
=
0
;
i
<
20
;
i
++
)
{
uint8_t
i_command
,
i_index
;
if
(
!
p_shuffle
->
p_commands
[
i
]
)
{
continue
;
}
i_command
=
(
p_shuffle
->
p_commands
[
i
]
&
0x300
)
>>
8
;
i_index
=
p_shuffle
->
p_commands
[
i
]
&
0xff
;
switch
(
i_command
)
{
case
0x3
:
p_bordel
[
i_index
&
0xf
]
=
p_bordel
[
i_index
>>
4
]
+
p_bordel
[
((
i_index
+
0x10
)
>>
4
)
&
0xf
];
break
;
case
0x2
:
p_bordel
[
i_index
>>
4
]
^=
p_shuffle_xor
[
0xff
-
i_index
];
break
;
case
0x1
:
p_bordel
[
i_index
>>
4
]
-=
p_shuffle_sub
[
0xff
-
i_index
];
break
;
default:
p_bordel
[
i_index
>>
4
]
+=
p_shuffle_add
[
0xff
-
i_index
];
break
;
}
}
if
(
p_shuffle
->
i_version
==
0x01000300
)
{
DoExtShuffle
(
p_bordel
);
}
/* Convert our newly randomised p_bordel to big endianness and take
* its MD5 hash. */
InitMD5
(
&
md5
);
for
(
i
=
0
;
i
<
16
;
i
++
)
{
p_big_bordel
[
i
]
=
U32_AT
(
p_bordel
+
i
);
}
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_big_bordel
,
64
);
if
(
p_shuffle
->
i_version
==
0x01000300
)
{
uint32_t
p_tmp3
[
i_secret3
];
char
p_tmp4
[
i_secret4
];
memcpy
(
p_tmp3
,
p_secret3
,
sizeof
(
p_secret3
)
);
REVERSE
(
p_tmp3
,
i_secret3
);
#define ROT13(c) (((c)>='A'&&(c)<='Z')?(((c)-'A'+13)%26)+'A':\
((c)>='a'&&(c)<='z')?(((c)-'a'+13)%26)+'a':c)
for
(
uint32_t
i
=
0
;
i
<
i_secret4
;
i
++
)
p_tmp4
[
i
]
=
ROT13
(
p_secret4
[
i
]
);
#undef ROT13
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_tmp3
,
sizeof
(
p_secret3
)
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_tmp4
,
i_secret4
);
}
EndMD5
(
&
md5
);
/* XOR our buffer with the computed checksum */
for
(
i
=
0
;
i
<
i_size
;
i
++
)
{
p_buffer
[
i
]
^=
U32_AT
(
md5
.
buf
+
(
4
*
i
));
}
}
/*****************************************************************************
* DoExtShuffle: extended shuffle
*****************************************************************************
* This is even uglier.
*****************************************************************************/
static
void
DoExtShuffle
(
uint32_t
*
p_bordel
)
{
uint32_t
i_ret
;
i_ret
=
FirstPass
(
p_bordel
);
SecondPass
(
p_bordel
,
i_ret
);
ThirdPass
(
p_bordel
);
FourthPass
(
p_bordel
);
}
static
uint32_t
FirstPass
(
uint32_t
*
p_bordel
)
{
uint32_t
i
,
i_cmd
,
i_ret
=
5
;
TinyShuffle1
(
p_bordel
);
for
(
;
;
)
{
for
(
;
;
)
{
p_bordel
[
1
]
+=
0x10000000
;
p_bordel
[
3
]
+=
0x12777
;
if
(
(
p_bordel
[
10
]
&
1
)
&&
i_ret
)
{
i_ret
--
;
p_bordel
[
1
]
-=
p_bordel
[
2
];
p_bordel
[
11
]
+=
p_bordel
[
12
];
break
;
}
if
(
(
p_bordel
[
1
]
+
p_bordel
[
2
])
>=
0x7D0
)
{
switch
(
((
p_bordel
[
3
]
^
0x567F
)
>>
2
)
&
7
)
{
case
0
:
for
(
i
=
0
;
i
<
3
;
i
++
)
{
if
(
p_bordel
[
i
+
10
]
>
0x4E20
)
{
p_bordel
[
i
+
1
]
+=
p_bordel
[
i
+
2
];
}
}
break
;
case
4
:
p_bordel
[
1
]
-=
p_bordel
[
2
];
/* no break */
case
3
:
p_bordel
[
11
]
+=
p_bordel
[
12
];
break
;
case
6
:
p_bordel
[
3
]
^=
p_bordel
[
4
];
/* no break */
case
8
:
p_bordel
[
13
]
&=
p_bordel
[
14
];
/* no break */
case
1
:
p_bordel
[
0
]
|=
p_bordel
[
1
];
if
(
i_ret
)
{
return
i_ret
;
}
break
;
}
break
;
}
}
for
(
i
=
0
,
i_cmd
=
0
;
i
<
16
;
i
++
)
{
if
(
p_bordel
[
i
]
<
p_bordel
[
i_cmd
]
)
{
i_cmd
=
i
;
}
}
if
(
i_ret
&&
i_cmd
!=
5
)
{
i_ret
--
;
}
else
{
if
(
i_cmd
==
5
)
{
p_bordel
[
8
]
&=
p_bordel
[
6
]
>>
1
;
p_bordel
[
3
]
<<=
1
;
}
for
(
i
=
0
;
i
<
3
;
i
++
)
{
p_bordel
[
11
]
+=
1
;
if
(
p_bordel
[
11
]
&
5
)
{
p_bordel
[
8
]
+=
p_bordel
[
9
];
}
else
if
(
i_ret
)
{
i_ret
--
;
i_cmd
=
3
;
goto
break2
;
}
}
i_cmd
=
(
p_bordel
[
15
]
+
0x93
)
>>
3
;
if
(
p_bordel
[
15
]
&
0x100
)
{
i_cmd
^=
0xDEAD
;
}
}
switch
(
i_cmd
&
3
)
{
case
0
:
while
(
p_bordel
[
11
]
&
1
)
{
p_bordel
[
11
]
>>=
1
;
p_bordel
[
12
]
+=
1
;
}
/* no break */
case
2
:
p_bordel
[
14
]
-=
0x19FE
;
break
;
case
3
:
if
(
i_ret
)
{
i_ret
--
;
p_bordel
[
5
]
+=
5
;
continue
;
}
break
;
}
i_cmd
=
((
p_bordel
[
3
]
+
p_bordel
[
4
]
+
10
)
>>
1
)
-
p_bordel
[
4
];
break
;
}
break2:
switch
(
i_cmd
&
3
)
{
case
0
:
p_bordel
[
14
]
>>=
1
;
break
;
case
1
:
p_bordel
[
5
]
<<=
2
;
break
;
case
2
:
p_bordel
[
12
]
|=
5
;
break
;
case
3
:
p_bordel
[
15
]
&=
0x55
;
if
(
i_ret
)
{
p_bordel
[
2
]
&=
0xB62FC
;
return
i_ret
;
}
break
;
}
TinyShuffle2
(
p_bordel
);
return
i_ret
;
}
static
void
SecondPass
(
uint32_t
*
p_bordel
,
uint32_t
i_tmp
)
{
uint32_t
i
,
i_cmd
,
i_jc
=
5
;
TinyShuffle3
(
p_bordel
);
for
(
i
=
0
,
i_cmd
=
0
;
i
<
16
;
i
++
)
{
if
(
p_bordel
[
i
]
>
p_bordel
[
i_cmd
]
)
{
i_cmd
=
i
;
}
}
switch
(
i_cmd
)
{
case
0
:
if
(
p_bordel
[
1
]
<
p_bordel
[
8
]
)
{
p_bordel
[
5
]
+=
1
;
}
break
;
case
4
:
if
(
(
p_bordel
[
9
]
&
0x7777
)
==
0x3333
)
{
p_bordel
[
5
]
-=
1
;
}
else
{
i_jc
--
;
if
(
p_bordel
[
1
]
<
p_bordel
[
8
]
)
{
p_bordel
[
5
]
+=
1
;
}
break
;
}
/* no break */
case
7
:
p_bordel
[
2
]
-=
1
;
p_bordel
[
1
]
-=
p_bordel
[
5
];
for
(
i
=
0
;
i
<
3
;
i
++
)
{
switch
(
p_bordel
[
1
]
&
3
)
{
case
0
:
p_bordel
[
1
]
+=
1
;
/* no break */
case
1
:
p_bordel
[
3
]
-=
8
;
break
;
case
2
:
p_bordel
[
13
]
&=
0xFEFEFEF7
;
break
;
case
3
:
p_bordel
[
8
]
|=
0x80080011
;
break
;
}
}
return
;
case
10
:
p_bordel
[
4
]
-=
1
;
p_bordel
[
5
]
+=
1
;
p_bordel
[
6
]
-=
1
;
p_bordel
[
7
]
+=
1
;
break
;
default:
p_bordel
[
15
]
^=
0x18547EFF
;
break
;
}
for
(
i
=
3
;
i
--
;
)
{
switch
(
(
p_bordel
[
12
]
+
p_bordel
[
13
]
+
p_bordel
[
6
]
)
%
5
)
{
case
0
:
p_bordel
[
12
]
-=
1
;
/* no break */
case
1
:
p_bordel
[
12
]
-=
1
;
p_bordel
[
13
]
+=
1
;
break
;
case
2
:
p_bordel
[
13
]
+=
4
;
/* no break */
case
3
:
p_bordel
[
12
]
-=
1
;
break
;
case
4
:
i_jc
--
;
p_bordel
[
5
]
+=
1
;
p_bordel
[
6
]
-=
1
;
p_bordel
[
7
]
+=
1
;
i
=
3
;
/* Restart the whole loop */
break
;
}
}
TinyShuffle4
(
p_bordel
);
for
(
;
;
)
{
TinyShuffle5
(
p_bordel
);
switch
(
(
p_bordel
[
2
]
*
2
+
15
)
%
5
)
{
case
0
:
if
(
(
p_bordel
[
3
]
+
i_tmp
)
<=
(
p_bordel
[
1
]
+
p_bordel
[
15
]
)
)
{
p_bordel
[
3
]
+=
1
;
}
break
;
case
4
:
p_bordel
[
10
]
-=
0x13
;
break
;
case
3
:
p_bordel
[
5
]
>>=
2
;
break
;
}
if
(
!
(
p_bordel
[
2
]
&
1
)
||
i_jc
==
0
)
{
break
;
}
i_jc
--
;
p_bordel
[
2
]
+=
0x13
;
p_bordel
[
12
]
+=
1
;
}
p_bordel
[
2
]
&=
0x10076000
;
}
static
void
ThirdPass
(
uint32_t
*
p_bordel
)
{
uint32_t
i_cmd
;
i_cmd
=
((
p_bordel
[
7
]
+
p_bordel
[
14
]
+
10
)
>>
1
)
-
p_bordel
[
14
];
i_cmd
=
i_cmd
%
10
;
switch
(
i_cmd
)
{
case
0
:
p_bordel
[
1
]
<<=
1
;
p_bordel
[
2
]
<<=
2
;
p_bordel
[
3
]
<<=
3
;
break
;
case
6
:
p_bordel
[
i_cmd
+
3
]
&=
0x5EDE36B
;
p_bordel
[
5
]
+=
p_bordel
[
8
];
p_bordel
[
4
]
+=
p_bordel
[
7
];
p_bordel
[
3
]
+=
p_bordel
[
6
];
p_bordel
[
2
]
+=
p_bordel
[
5
];
/* no break */
case
2
:
p_bordel
[
1
]
+=
p_bordel
[
4
];
p_bordel
[
0
]
+=
p_bordel
[
3
];
TinyShuffle6
(
p_bordel
);
return
;
/* jc = 4 */
case
3
:
if
(
(
p_bordel
[
11
]
&
p_bordel
[
2
])
>
0x211B
)
{
p_bordel
[
6
]
+=
1
;
}
break
;
case
4
:
p_bordel
[
7
]
+=
1
;
/* no break */
case
5
:
p_bordel
[
9
]
^=
p_bordel
[
2
];
break
;
case
7
:
p_bordel
[
2
]
^=
(
p_bordel
[
1
]
&
p_bordel
[
13
]);
break
;
case
8
:
p_bordel
[
0
]
-=
p_bordel
[
11
]
&
p_bordel
[
15
];
return
;
/* jc = 4 */
case
9
:
p_bordel
[
6
]
>>=
(
p_bordel
[
14
]
&
3
);
break
;
}
SWAP
(
p_bordel
[
0
],
p_bordel
[
10
]
);
TinyShuffle6
(
p_bordel
);
return
;
/* jc = 5 */
}
static
void
FourthPass
(
uint32_t
*
p_bordel
)
{
uint32_t
i
,
j
;
TinyShuffle7
(
p_bordel
);
switch
(
p_bordel
[
5
]
%
5
)
{
case
0
:
p_bordel
[
0
]
+=
1
;
break
;
case
2
:
p_bordel
[
11
]
^=
(
p_bordel
[
3
]
+
p_bordel
[
6
]
+
p_bordel
[
8
]);
break
;
case
3
:
for
(
i
=
4
;
i
<
15
&&
(
p_bordel
[
i
]
&
5
)
==
0
;
i
++
)
{
SWAP
(
p_bordel
[
i
],
p_bordel
[
15
-
i
]
);
}
break
;
case
4
:
p_bordel
[
12
]
-=
1
;
p_bordel
[
13
]
+=
1
;
p_bordel
[
2
]
-=
0x64
;
p_bordel
[
3
]
+=
0x64
;
TinyShuffle8
(
p_bordel
);
return
;
}
for
(
i
=
0
,
j
=
0
;
i
<
16
;
i
++
)
{
if
(
p_bordel
[
i
]
>
p_bordel
[
j
]
)
{
j
=
i
;
}
}
switch
(
p_bordel
[
j
]
%
100
)
{
case
0
:
SWAP
(
p_bordel
[
0
],
p_bordel
[
j
]
);
break
;
case
8
:
p_bordel
[
1
]
>>=
1
;
p_bordel
[
2
]
<<=
1
;
p_bordel
[
14
]
>>=
3
;
p_bordel
[
15
]
<<=
4
;
break
;
case
57
:
p_bordel
[
j
]
+=
p_bordel
[
13
];
break
;
case
76
:
p_bordel
[
1
]
+=
0x20E
;
p_bordel
[
5
]
+=
0x223D
;
p_bordel
[
13
]
-=
0x576
;
p_bordel
[
15
]
+=
0x576
;
return
;
case
91
:
p_bordel
[
2
]
-=
0x64
;
p_bordel
[
3
]
+=
0x64
;
p_bordel
[
12
]
-=
1
;
p_bordel
[
13
]
+=
1
;
break
;
case
99
:
p_bordel
[
0
]
+=
1
;
p_bordel
[
j
]
+=
p_bordel
[
13
];
break
;
}
TinyShuffle8
(
p_bordel
);
}
/*****************************************************************************
* TinyShuffle[12345678]: tiny shuffle subroutines
*****************************************************************************
* These standalone functions are little helpers for the shuffling process.
*****************************************************************************/
static
void
TinyShuffle1
(
uint32_t
*
p_bordel
)
{
uint32_t
i_cmd
=
(
p_bordel
[
5
]
+
10
)
>>
2
;
if
(
p_bordel
[
5
]
>
0x7D0
)
{
i_cmd
-=
0x305
;
}
switch
(
i_cmd
&
3
)
{
case
0
:
p_bordel
[
5
]
+=
5
;
break
;
case
1
:
p_bordel
[
4
]
-=
1
;
break
;
case
2
:
if
(
p_bordel
[
4
]
&
5
)
{
p_bordel
[
1
]
^=
0x4D
;
}
/* no break */
case
3
:
p_bordel
[
12
]
+=
5
;
break
;
}
}
static
void
TinyShuffle2
(
uint32_t
*
p_bordel
)
{
uint32_t
i
,
j
;
for
(
i
=
0
,
j
=
0
;
i
<
16
;
i
++
)
{
if
(
(
p_bordel
[
i
]
&
0x777
)
>
(
p_bordel
[
j
]
&
0x777
)
)
{
j
=
i
;
}
}
if
(
j
>
5
)
{
for
(
;
j
<
15
;
j
++
)
{
p_bordel
[
j
]
+=
p_bordel
[
j
+
1
];
}
}
else
{
p_bordel
[
2
]
&=
0xB62FC
;
}
}
static
void
TinyShuffle3
(
uint32_t
*
p_bordel
)
{
uint32_t
i_cmd
=
p_bordel
[
6
]
+
0x194B
;
if
(
p_bordel
[
6
]
>
0x2710
)
{
i_cmd
>>=
1
;
}
switch
(
i_cmd
&
3
)
{
case
1
:
p_bordel
[
3
]
+=
0x19FE
;
break
;
case
2
:
p_bordel
[
7
]
-=
p_bordel
[
3
]
>>
2
;
/* no break */
case
0
:
p_bordel
[
5
]
^=
0x248A
;
break
;
}
}
static
void
TinyShuffle4
(
uint32_t
*
p_bordel
)
{
uint32_t
i
,
j
;
for
(
i
=
0
,
j
=
0
;
i
<
16
;
i
++
)
{
if
(
p_bordel
[
i
]
<
p_bordel
[
j
]
)
{
j
=
i
;
}
}
if
(
(
p_bordel
[
j
]
%
(
j
+
1
))
>
10
)
{
p_bordel
[
1
]
-=
1
;
p_bordel
[
2
]
+=
0x13
;
p_bordel
[
12
]
+=
1
;
}
}
static
void
TinyShuffle5
(
uint32_t
*
p_bordel
)
{
uint32_t
i
;
p_bordel
[
2
]
&=
0x7F3F
;
for
(
i
=
0
;
i
<
5
;
i
++
)
{
switch
(
(
p_bordel
[
2
]
+
10
+
i
)
%
5
)
{
case
0
:
p_bordel
[
12
]
&=
p_bordel
[
2
];
/* no break */
case
1
:
p_bordel
[
3
]
^=
p_bordel
[
15
];
break
;
case
2
:
p_bordel
[
15
]
+=
0x576
;
/* no break */
case
3
:
p_bordel
[
7
]
-=
0x2D
;
/* no break */
case
4
:
p_bordel
[
1
]
<<=
1
;
break
;
}
}
}
static
void
TinyShuffle6
(
uint32_t
*
p_bordel
)
{
uint32_t
i
,
j
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
j
=
p_bordel
[
3
]
&
0x7514
?
5
:
7
;
SWAP
(
p_bordel
[
i
],
p_bordel
[
i
+
j
]
);
}
}
static
void
TinyShuffle7
(
uint32_t
*
p_bordel
)
{
uint32_t
i
;
i
=
(((
p_bordel
[
9
]
+
p_bordel
[
15
]
+
12
)
>>
2
)
-
p_bordel
[
4
])
&
7
;
while
(
i
--
)
{
SWAP
(
p_bordel
[
i
],
p_bordel
[
i
+
3
]
);
}
SWAP
(
p_bordel
[
1
],
p_bordel
[
10
]
);
}
static
void
TinyShuffle8
(
uint32_t
*
p_bordel
)
{
uint32_t
i
;
i
=
(
p_bordel
[
0
]
&
p_bordel
[
6
])
&
0xF
;
switch
(
p_bordel
[
i
]
%
1000
)
{
case
7
:
if
(
(
p_bordel
[
i
]
&
0x777
)
>
(
p_bordel
[
7
]
&
0x5555
)
)
{
p_bordel
[
i
]
^=
p_bordel
[
5
]
&
p_bordel
[
3
];
}
break
;
case
19
:
p_bordel
[
15
]
&=
0x5555
;
break
;
case
93
:
p_bordel
[
i
]
^=
p_bordel
[
15
];
break
;
case
100
:
SWAP
(
p_bordel
[
0
],
p_bordel
[
3
]
);
SWAP
(
p_bordel
[
1
],
p_bordel
[
6
]
);
SWAP
(
p_bordel
[
3
],
p_bordel
[
6
]
);
SWAP
(
p_bordel
[
4
],
p_bordel
[
9
]
);
SWAP
(
p_bordel
[
5
],
p_bordel
[
8
]
);
SWAP
(
p_bordel
[
6
],
p_bordel
[
7
]
);
SWAP
(
p_bordel
[
13
],
p_bordel
[
14
]
);
break
;
case
329
:
p_bordel
[
i
]
+=
p_bordel
[
1
]
^
0x80080011
;
p_bordel
[
i
]
+=
p_bordel
[
2
]
^
0xBEEFDEAD
;
p_bordel
[
i
]
+=
p_bordel
[
3
]
^
0x8765F444
;
p_bordel
[
i
]
+=
p_bordel
[
4
]
^
0x78145326
;
break
;
case
567
:
p_bordel
[
12
]
-=
p_bordel
[
i
];
p_bordel
[
13
]
+=
p_bordel
[
i
];
break
;
case
612
:
p_bordel
[
i
]
+=
p_bordel
[
1
];
p_bordel
[
i
]
-=
p_bordel
[
7
];
p_bordel
[
i
]
-=
p_bordel
[
8
];
p_bordel
[
i
]
+=
p_bordel
[
9
];
p_bordel
[
i
]
+=
p_bordel
[
13
];
break
;
case
754
:
i
=
__MIN
(
i
,
12
);
p_bordel
[
i
+
1
]
>>=
1
;
p_bordel
[
i
+
2
]
<<=
4
;
p_bordel
[
i
+
3
]
>>=
3
;
break
;
case
777
:
p_bordel
[
1
]
+=
0x20E
;
p_bordel
[
5
]
+=
0x223D
;
p_bordel
[
13
]
-=
0x576
;
p_bordel
[
15
]
+=
0x576
;
break
;
case
981
:
if
(
(
p_bordel
[
i
]
^
0x8765F441
)
<
0x2710
)
{
SWAP
(
p_bordel
[
0
],
p_bordel
[
1
]
);
}
else
{
SWAP
(
p_bordel
[
1
],
p_bordel
[
11
]
);
}
break
;
}
}
/*****************************************************************************
* GetSystemKey: get the system key
*****************************************************************************
* Compute the system key from various system information, see HashSystemInfo.
*****************************************************************************/
static
int
GetSystemKey
(
uint32_t
*
p_sys_key
,
bool
b_ipod
)
{
static
const
char
p_secret5
[
8
]
=
"YuaFlafu"
;
static
const
char
p_secret6
[
8
]
=
"zPif98ga"
;
struct
md5_s
md5
;
int64_t
i_ipod_id
;
uint32_t
p_system_hash
[
4
];
/* Compute the MD5 hash of our system info */
if
(
(
!
b_ipod
&&
HashSystemInfo
(
p_system_hash
)
)
||
(
b_ipod
&&
GetiPodID
(
&
i_ipod_id
)
)
)
{
return
-
1
;
}
/* Combine our system info hash with additional secret data. The resulting
* MD5 hash will be our system key. */
InitMD5
(
&
md5
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_secret5
,
8
);
if
(
!
b_ipod
)
{
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_system_hash
,
6
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_system_hash
,
6
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_system_hash
,
6
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_secret6
,
8
);
}
else
{
i_ipod_id
=
U64_AT
(
&
i_ipod_id
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
&
i_ipod_id
,
sizeof
(
i_ipod_id
)
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
&
i_ipod_id
,
sizeof
(
i_ipod_id
)
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
&
i_ipod_id
,
sizeof
(
i_ipod_id
)
);
}
EndMD5
(
&
md5
);
memcpy
(
p_sys_key
,
md5
.
buf
,
16
);
return
0
;
}
#ifdef WIN32
# define DRMS_DIRNAME "drms"
#else
# define DRMS_DIRNAME ".drms"
#endif
/*****************************************************************************
* WriteUserKey: write the user key to hard disk
*****************************************************************************
* Write the user key to the hard disk so that it can be reused later or used
* on operating systems other than Win32.
*****************************************************************************/
static
int
WriteUserKey
(
void
*
_p_drms
,
uint32_t
*
p_user_key
)
{
struct
drms_s
*
p_drms
=
(
struct
drms_s
*
)
_p_drms
;
FILE
*
file
;
int
i_ret
=
-
1
;
char
psz_path
[
PATH_MAX
];
snprintf
(
psz_path
,
PATH_MAX
-
1
,
"%s/"
DRMS_DIRNAME
,
p_drms
->
psz_homedir
);
#if defined( WIN32 )
if
(
!
mkdir
(
psz_path
)
||
errno
==
EEXIST
)
#else
if
(
!
mkdir
(
psz_path
,
0755
)
||
errno
==
EEXIST
)
#endif
{
snprintf
(
psz_path
,
PATH_MAX
-
1
,
"%s/"
DRMS_DIRNAME
"/%08X.%03d"
,
p_drms
->
psz_homedir
,
p_drms
->
i_user
,
p_drms
->
i_key
);
file
=
vlc_fopen
(
psz_path
,
"wb"
);
if
(
file
!=
NULL
)
{
i_ret
=
fwrite
(
p_user_key
,
sizeof
(
uint32_t
),
4
,
file
)
==
4
?
0
:
-
1
;
fclose
(
file
);
}
}
return
i_ret
;
}
/*****************************************************************************
* ReadUserKey: read the user key from hard disk
*****************************************************************************
* Retrieve the user key from the hard disk if available.
*****************************************************************************/
static
int
ReadUserKey
(
void
*
_p_drms
,
uint32_t
*
p_user_key
)
{
struct
drms_s
*
p_drms
=
(
struct
drms_s
*
)
_p_drms
;
FILE
*
file
;
int
i_ret
=
-
1
;
char
psz_path
[
PATH_MAX
];
snprintf
(
psz_path
,
PATH_MAX
-
1
,
"%s/"
DRMS_DIRNAME
"/%08X.%03d"
,
p_drms
->
psz_homedir
,
p_drms
->
i_user
,
p_drms
->
i_key
);
file
=
vlc_fopen
(
psz_path
,
"rb"
);
if
(
file
!=
NULL
)
{
i_ret
=
fread
(
p_user_key
,
sizeof
(
uint32_t
),
4
,
file
)
==
4
?
0
:
-
1
;
fclose
(
file
);
}
return
i_ret
;
}
/*****************************************************************************
* GetUserKey: get the user key
*****************************************************************************
* Retrieve the user key from the hard disk if available, otherwise generate
* it from the system key. If the key could be successfully generated, write
* it to the hard disk for future use.
*****************************************************************************/
static
int
GetUserKey
(
void
*
_p_drms
,
uint32_t
*
p_user_key
)
{
static
const
char
p_secret7
[]
=
"mUfnpognadfgf873"
;
struct
drms_s
*
p_drms
=
(
struct
drms_s
*
)
_p_drms
;
struct
aes_s
aes
;
struct
shuffle_s
shuffle
;
uint32_t
i
,
y
;
uint32_t
*
p_sci_data
=
NULL
;
uint32_t
i_user
,
i_key
;
uint32_t
p_sys_key
[
4
];
uint32_t
i_sci_size
=
0
,
i_blocks
,
i_remaining
;
uint32_t
*
p_sci0
,
*
p_sci1
,
*
p_buffer
;
uint32_t
p_sci_key
[
4
];
char
*
psz_ipod
;
int
i_ret
=
-
5
;
if
(
ReadUserKey
(
p_drms
,
p_user_key
)
==
0
)
{
REVERSE
(
p_user_key
,
4
);
return
0
;
}
psz_ipod
=
getenv
(
"IPOD"
);
if
(
GetSystemKey
(
p_sys_key
,
psz_ipod
?
true
:
false
)
)
{
return
-
3
;
}
if
(
GetSCIData
(
psz_ipod
,
&
p_sci_data
,
&
i_sci_size
)
)
{
return
-
4
;
}
/* Phase 1: unscramble the SCI data using the system key and shuffle
* it using DoShuffle(). */
/* Skip the first 4 bytes (some sort of header). Decrypt the rest. */
i_blocks
=
(
i_sci_size
-
4
)
/
16
;
i_remaining
=
(
i_sci_size
-
4
)
-
(
i_blocks
*
16
);
p_buffer
=
p_sci_data
+
1
;
/* Decrypt and shuffle our data at the same time */
InitAES
(
&
aes
,
p_sys_key
);
REVERSE
(
p_sys_key
,
4
);
REVERSE
(
p_sci_data
,
1
);
InitShuffle
(
&
shuffle
,
p_sys_key
,
p_sci_data
[
0
]
);
memcpy
(
p_sci_key
,
p_secret7
,
16
);
REVERSE
(
p_sci_key
,
4
);
while
(
i_blocks
--
)
{
uint32_t
p_tmp
[
4
];
REVERSE
(
p_buffer
,
4
);
DecryptAES
(
&
aes
,
p_tmp
,
p_buffer
);
BlockXOR
(
p_tmp
,
p_sci_key
,
p_tmp
);
/* Use the previous scrambled data as the key for next block */
memcpy
(
p_sci_key
,
p_buffer
,
16
);
/* Shuffle the decrypted data using a custom routine */
DoShuffle
(
&
shuffle
,
p_tmp
,
4
);
/* Copy this block back to p_buffer */
memcpy
(
p_buffer
,
p_tmp
,
16
);
p_buffer
+=
4
;
}
if
(
i_remaining
>=
4
)
{
REVERSE
(
p_buffer
,
i_remaining
/
4
);
DoShuffle
(
&
shuffle
,
p_buffer
,
i_remaining
/
4
);
}
/* Phase 2: look for the user key in the generated data. I must admit I
* do not understand what is going on here, because it almost
* looks like we are browsing data that makes sense, even though
* the DoShuffle() part made it completely meaningless. */
y
=
0
;
REVERSE
(
p_sci_data
+
5
,
1
);
i
=
U32_AT
(
p_sci_data
+
5
);
i_sci_size
-=
22
*
sizeof
(
uint32_t
);
p_sci1
=
p_sci_data
+
22
;
p_sci0
=
NULL
;
while
(
i_sci_size
>=
20
&&
i
>
0
)
{
if
(
p_sci0
==
NULL
)
{
i_sci_size
-=
18
*
sizeof
(
uint32_t
);
if
(
i_sci_size
<
20
)
{
break
;
}
p_sci0
=
p_sci1
;
REVERSE
(
p_sci1
+
17
,
1
);
y
=
U32_AT
(
p_sci1
+
17
);
p_sci1
+=
18
;
}
if
(
!
y
)
{
i
--
;
p_sci0
=
NULL
;
continue
;
}
i_user
=
U32_AT
(
p_sci0
);
i_key
=
U32_AT
(
p_sci1
);
REVERSE
(
&
i_user
,
1
);
REVERSE
(
&
i_key
,
1
);
if
(
i_user
==
p_drms
->
i_user
&&
(
(
i_key
==
p_drms
->
i_key
)
||
(
!
p_drms
->
i_key
&&
(
p_sci1
==
(
p_sci0
+
18
)
)
)
)
)
{
memcpy
(
p_user_key
,
p_sci1
+
1
,
16
);
REVERSE
(
p_sci1
+
1
,
4
);
WriteUserKey
(
p_drms
,
p_sci1
+
1
);
i_ret
=
0
;
break
;
}
y
--
;
p_sci1
+=
5
;
i_sci_size
-=
5
*
sizeof
(
uint32_t
);
}
free
(
p_sci_data
);
return
i_ret
;
}
/*****************************************************************************
* GetSCIData: get SCI data from "SC Info.sidb"
*****************************************************************************
* Read SCI data from "\Apple Computer\iTunes\SC Info\SC Info.sidb"
*****************************************************************************/
static
int
GetSCIData
(
char
*
psz_ipod
,
uint32_t
**
pp_sci
,
uint32_t
*
pi_sci_size
)
{
FILE
*
file
;
char
*
psz_path
=
NULL
;
char
p_tmp
[
4
*
PATH_MAX
];
int
i_ret
=
-
1
;
if
(
psz_ipod
==
NULL
)
{
#ifdef WIN32
const
char
*
SCIfile
=
"
\\
Apple Computer
\\
iTunes
\\
SC Info
\\
SC Info.sidb"
;
strncpy
(
p_tmp
,
config_GetConfDir
(),
sizeof
(
p_tmp
)
-
1
);
if
(
strlen
(
p_tmp
)
+
strlen
(
SCIfile
)
>=
PATH_MAX
)
return
-
1
;
strcat
(
p_tmp
,
SCIfile
);
p_tmp
[
sizeof
(
p_tmp
)
-
1
]
=
'\0'
;
psz_path
=
p_tmp
;
#endif
}
else
{
#define ISCINFO "iSCInfo"
if
(
strstr
(
psz_ipod
,
ISCINFO
)
==
NULL
)
{
snprintf
(
p_tmp
,
sizeof
(
p_tmp
)
-
1
,
"%s/iPod_Control/iTunes/"
ISCINFO
"2"
,
psz_ipod
);
psz_path
=
p_tmp
;
}
else
{
psz_path
=
psz_ipod
;
}
}
if
(
psz_path
==
NULL
)
{
return
-
1
;
}
file
=
vlc_fopen
(
psz_path
,
"rb"
);
if
(
file
!=
NULL
)
{
struct
stat
st
;
if
(
!
fstat
(
fileno
(
file
),
&
st
)
&&
st
.
st_size
>=
4
)
{
*
pp_sci
=
malloc
(
st
.
st_size
);
if
(
*
pp_sci
!=
NULL
)
{
if
(
fread
(
*
pp_sci
,
1
,
st
.
st_size
,
file
)
==
(
size_t
)
st
.
st_size
)
{
*
pi_sci_size
=
st
.
st_size
;
i_ret
=
0
;
}
else
{
free
(
(
void
*
)
*
pp_sci
);
*
pp_sci
=
NULL
;
}
}
}
fclose
(
file
);
}
return
i_ret
;
}
/*****************************************************************************
* HashSystemInfo: hash system information
*****************************************************************************
* This function computes the MD5 hash of the C: hard drive serial number,
* BIOS version, CPU type and Windows version.
*****************************************************************************/
static
int
HashSystemInfo
(
uint32_t
*
p_system_hash
)
{
struct
md5_s
md5
;
int
i_ret
=
0
;
#ifdef WIN32
HKEY
i_key
;
unsigned
int
i
;
DWORD
i_size
;
DWORD
i_serial
;
LPBYTE
p_reg_buf
;
static
const
LPCTSTR
p_reg_keys
[
3
][
2
]
=
{
{
_T
(
"HARDWARE
\\
DESCRIPTION
\\
System"
),
_T
(
"SystemBiosVersion"
)
},
{
_T
(
"HARDWARE
\\
DESCRIPTION
\\
System
\\
CentralProcessor
\\
0"
),
_T
(
"ProcessorNameString"
)
},
{
_T
(
"SOFTWARE
\\
Microsoft
\\
Windows
\\
CurrentVersion"
),
_T
(
"ProductId"
)
}
};
InitMD5
(
&
md5
);
AddMD5
(
&
md5
,
"cache-control"
,
13
);
AddMD5
(
&
md5
,
"Ethernet"
,
8
);
GetVolumeInformation
(
_T
(
"C:
\\
"
),
NULL
,
0
,
&
i_serial
,
NULL
,
NULL
,
NULL
,
0
);
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
&
i_serial
,
4
);
for
(
i
=
0
;
i
<
sizeof
(
p_reg_keys
)
/
sizeof
(
p_reg_keys
[
0
]);
i
++
)
{
if
(
RegOpenKeyEx
(
HKEY_LOCAL_MACHINE
,
p_reg_keys
[
i
][
0
],
0
,
KEY_READ
,
&
i_key
)
!=
ERROR_SUCCESS
)
{
continue
;
}
if
(
RegQueryValueEx
(
i_key
,
p_reg_keys
[
i
][
1
],
NULL
,
NULL
,
NULL
,
&
i_size
)
!=
ERROR_SUCCESS
)
{
RegCloseKey
(
i_key
);
continue
;
}
p_reg_buf
=
malloc
(
i_size
);
if
(
p_reg_buf
!=
NULL
)
{
if
(
RegQueryValueEx
(
i_key
,
p_reg_keys
[
i
][
1
],
NULL
,
NULL
,
p_reg_buf
,
&
i_size
)
==
ERROR_SUCCESS
)
{
AddMD5
(
&
md5
,
(
const
uint8_t
*
)
p_reg_buf
,
i_size
);
}
free
(
p_reg_buf
);
}
RegCloseKey
(
i_key
);
}
#else
InitMD5
(
&
md5
);
i_ret
=
-
1
;
#endif
EndMD5
(
&
md5
);
memcpy
(
p_system_hash
,
md5
.
buf
,
16
);
return
i_ret
;
}
/*****************************************************************************
* GetiPodID: Get iPod ID
*****************************************************************************
* This function gets the iPod ID.
*****************************************************************************/
static
int
GetiPodID
(
int64_t
*
p_ipod_id
)
{
int
i_ret
=
-
1
;
#define PROD_NAME "iPod"
#define VENDOR_NAME "Apple Computer, Inc."
char
*
psz_ipod_id
=
getenv
(
"IPODID"
);
if
(
psz_ipod_id
!=
NULL
)
{
*
p_ipod_id
=
strtoll
(
psz_ipod_id
,
NULL
,
16
);
return
0
;
}
#ifdef HAVE_MACOS_IOKIT
CFTypeRef
value
;
mach_port_t
port
;
io_object_t
device
;
io_iterator_t
iterator
;
CFMutableDictionaryRef
match_dic
;
CFMutableDictionaryRef
smatch_dic
;
if
(
IOMasterPort
(
MACH_PORT_NULL
,
&
port
)
==
KERN_SUCCESS
)
{
smatch_dic
=
IOServiceMatching
(
"IOFireWireUnit"
);
match_dic
=
CFDictionaryCreateMutable
(
kCFAllocatorDefault
,
0
,
&
kCFTypeDictionaryKeyCallBacks
,
&
kCFTypeDictionaryValueCallBacks
);
if
(
smatch_dic
!=
NULL
&&
match_dic
!=
NULL
)
{
CFDictionarySetValue
(
smatch_dic
,
CFSTR
(
"FireWire Vendor Name"
),
CFSTR
(
VENDOR_NAME
)
);
CFDictionarySetValue
(
smatch_dic
,
CFSTR
(
"FireWire Product Name"
),
CFSTR
(
PROD_NAME
)
);
CFDictionarySetValue
(
match_dic
,
CFSTR
(
kIOPropertyMatchKey
),
smatch_dic
);
CFRelease
(
smatch_dic
);
if
(
IOServiceGetMatchingServices
(
port
,
match_dic
,
&
iterator
)
==
KERN_SUCCESS
)
{
while
(
(
device
=
IOIteratorNext
(
iterator
)
)
!=
0
)
{
value
=
IORegistryEntryCreateCFProperty
(
device
,
CFSTR
(
"GUID"
),
kCFAllocatorDefault
,
kNilOptions
);
if
(
value
!=
NULL
)
{
if
(
CFGetTypeID
(
value
)
==
CFNumberGetTypeID
()
)
{
int64_t
i_ipod_id
;
CFNumberGetValue
(
(
CFNumberRef
)
value
,
kCFNumberLongLongType
,
&
i_ipod_id
);
*
p_ipod_id
=
i_ipod_id
;
i_ret
=
0
;
}
CFRelease
(
value
);
}
IOObjectRelease
(
device
);
if
(
!
i_ret
)
break
;
}
IOObjectRelease
(
iterator
);
}
}
else
{
if
(
match_dic
)
CFRelease
(
match_dic
);
if
(
smatch_dic
)
CFRelease
(
smatch_dic
);
}
mach_port_deallocate
(
mach_task_self
(),
port
);
}
#endif
return
i_ret
;
}
#else
/* !defined( UNDER_CE ) */
void
*
drms_alloc
(
const
char
*
psz_homedir
){
return
NULL
;
}
void
drms_free
(
void
*
a
){}
void
drms_decrypt
(
void
*
a
,
uint32_t
*
b
,
uint32_t
c
,
uint32_t
*
k
){}
void
drms_get_p_key
(
void
*
p_drms
,
uint32_t
*
p_key
){}
int
drms_init
(
void
*
a
,
uint32_t
b
,
uint8_t
*
c
,
uint32_t
d
){
return
-
1
;
}
#endif
/* defined( UNDER_CE ) */
modules/demux/mp4/drms.h
deleted
100644 → 0
View file @
790d3d45
/*****************************************************************************
* drms.h : DRMS
*****************************************************************************
* Copyright (C) 2004 the VideoLAN team
* $Id$
*
* Author: Jon Lech Johansen <jon-vl@nanocrew.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef _VLC_DRMS_H
#define _VLC_DRMS_H 1
extern
void
*
drms_alloc
(
const
char
*
psz_homedir
);
extern
void
drms_free
(
void
*
p_drms
);
extern
int
drms_init
(
void
*
p_drms
,
uint32_t
i_type
,
uint8_t
*
p_info
,
uint32_t
i_len
);
extern
void
drms_decrypt
(
void
*
p_drms
,
uint32_t
*
p_buffer
,
uint32_t
i_len
,
uint32_t
*
p_key
);
extern
void
drms_get_p_key
(
void
*
p_drms
,
uint32_t
*
p_key
);
#endif
modules/demux/mp4/drmstables.h
deleted
100644 → 0
View file @
790d3d45
/*****************************************************************************
* drmstables.h : AES/Rijndael block cipher and miscellaneous tables
*****************************************************************************
* Copyright (C) 2004, 2006 the VideoLAN team
* $Id$
*
* Author: Jon Lech Johansen <jon-vl@nanocrew.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* p_aes_table, p_aes_encrypt, p_aes_itable, p_aes_decrypt: AES tables
*****************************************************************************
* The following tables and macros are used for the AES (Rijndael) cypher.
*****************************************************************************/
#define AES_ROR( x, n ) (((x) << (32-(n))) | ((x) >> (n)))
#define AES_XOR_ROR( p_table, p_tmp ) \
( p_table[ (p_tmp[ t > 2 ? t - 3 : t + 1 ] >> 24) & 0xFF ] \
^ AES_ROR( p_table[ (p_tmp[ t > 1 ? t - 2 : t + 2 ] >> 16) & 0xFF ], 8 ) \
^ AES_ROR( p_table[ (p_tmp[ t > 0 ? t - 1 : t + 3 ] >> 8) & 0xFF ], 16 ) \
^ AES_ROR( p_table[ p_tmp[ t ] & 0xFF ], 24 ) )
#define AES_KEY_COUNT 10
static
uint32_t
const
p_aes_table
[
AES_KEY_COUNT
]
=
{
0x00000001
,
0x00000002
,
0x00000004
,
0x00000008
,
0x00000010
,
0x00000020
,
0x00000040
,
0x00000080
,
0x0000001b
,
0x00000036
};
static
uint32_t
const
p_aes_encrypt
[
256
]
=
{
0x63000000
,
0x7c000000
,
0x77000000
,
0x7b000000
,
0xf2000000
,
0x6b000000
,
0x6f000000
,
0xc5000000
,
0x30000000
,
0x01000000
,
0x67000000
,
0x2b000000
,
0xfe000000
,
0xd7000000
,
0xab000000
,
0x76000000
,
0xca000000
,
0x82000000
,
0xc9000000
,
0x7d000000
,
0xfa000000
,
0x59000000
,
0x47000000
,
0xf0000000
,
0xad000000
,
0xd4000000
,
0xa2000000
,
0xaf000000
,
0x9c000000
,
0xa4000000
,
0x72000000
,
0xc0000000
,
0xb7000000
,
0xfd000000
,
0x93000000
,
0x26000000
,
0x36000000
,
0x3f000000
,
0xf7000000
,
0xcc000000
,
0x34000000
,
0xa5000000
,
0xe5000000
,
0xf1000000
,
0x71000000
,
0xd8000000
,
0x31000000
,
0x15000000
,
0x04000000
,
0xc7000000
,
0x23000000
,
0xc3000000
,
0x18000000
,
0x96000000
,
0x05000000
,
0x9a000000
,
0x07000000
,
0x12000000
,
0x80000000
,
0xe2000000
,
0xeb000000
,
0x27000000
,
0xb2000000
,
0x75000000
,
0x09000000
,
0x83000000
,
0x2c000000
,
0x1a000000
,
0x1b000000
,
0x6e000000
,
0x5a000000
,
0xa0000000
,
0x52000000
,
0x3b000000
,
0xd6000000
,
0xb3000000
,
0x29000000
,
0xe3000000
,
0x2f000000
,
0x84000000
,
0x53000000
,
0xd1000000
,
0x00000000
,
0xed000000
,
0x20000000
,
0xfc000000
,
0xb1000000
,
0x5b000000
,
0x6a000000
,
0xcb000000
,
0xbe000000
,
0x39000000
,
0x4a000000
,
0x4c000000
,
0x58000000
,
0xcf000000
,
0xd0000000
,
0xef000000
,
0xaa000000
,
0xfb000000
,
0x43000000
,
0x4d000000
,
0x33000000
,
0x85000000
,
0x45000000
,
0xf9000000
,
0x02000000
,
0x7f000000
,
0x50000000
,
0x3c000000
,
0x9f000000
,
0xa8000000
,
0x51000000
,
0xa3000000
,
0x40000000
,
0x8f000000
,
0x92000000
,
0x9d000000
,
0x38000000
,
0xf5000000
,
0xbc000000
,
0xb6000000
,
0xda000000
,
0x21000000
,
0x10000000
,
0xff000000
,
0xf3000000
,
0xd2000000
,
0xcd000000
,
0x0c000000
,
0x13000000
,
0xec000000
,
0x5f000000
,
0x97000000
,
0x44000000
,
0x17000000
,
0xc4000000
,
0xa7000000
,
0x7e000000
,
0x3d000000
,
0x64000000
,
0x5d000000
,
0x19000000
,
0x73000000
,
0x60000000
,
0x81000000
,
0x4f000000
,
0xdc000000
,
0x22000000
,
0x2a000000
,
0x90000000
,
0x88000000
,
0x46000000
,
0xee000000
,
0xb8000000
,
0x14000000
,
0xde000000
,
0x5e000000
,
0x0b000000
,
0xdb000000
,
0xe0000000
,
0x32000000
,
0x3a000000
,
0x0a000000
,
0x49000000
,
0x06000000
,
0x24000000
,
0x5c000000
,
0xc2000000
,
0xd3000000
,
0xac000000
,
0x62000000
,
0x91000000
,
0x95000000
,
0xe4000000
,
0x79000000
,
0xe7000000
,
0xc8000000
,
0x37000000
,
0x6d000000
,
0x8d000000
,
0xd5000000
,
0x4e000000
,
0xa9000000
,
0x6c000000
,
0x56000000
,
0xf4000000
,
0xea000000
,
0x65000000
,
0x7a000000
,
0xae000000
,
0x08000000
,
0xba000000
,
0x78000000
,
0x25000000
,
0x2e000000
,
0x1c000000
,
0xa6000000
,
0xb4000000
,
0xc6000000
,
0xe8000000
,
0xdd000000
,
0x74000000
,
0x1f000000
,
0x4b000000
,
0xbd000000
,
0x8b000000
,
0x8a000000
,
0x70000000
,
0x3e000000
,
0xb5000000
,
0x66000000
,
0x48000000
,
0x03000000
,
0xf6000000
,
0x0e000000
,
0x61000000
,
0x35000000
,
0x57000000
,
0xb9000000
,
0x86000000
,
0xc1000000
,
0x1d000000
,
0x9e000000
,
0xe1000000
,
0xf8000000
,
0x98000000
,
0x11000000
,
0x69000000
,
0xd9000000
,
0x8e000000
,
0x94000000
,
0x9b000000
,
0x1e000000
,
0x87000000
,
0xe9000000
,
0xce000000
,
0x55000000
,
0x28000000
,
0xdf000000
,
0x8c000000
,
0xa1000000
,
0x89000000
,
0x0d000000
,
0xbf000000
,
0xe6000000
,
0x42000000
,
0x68000000
,
0x41000000
,
0x99000000
,
0x2d000000
,
0x0f000000
,
0xb0000000
,
0x54000000
,
0xbb000000
,
0x16000000
};
static
uint32_t
const
p_aes_itable
[
256
]
=
{
0x5150a7f4
,
0x7e536541
,
0x1ac3a417
,
0x3a965e27
,
0x3bcb6bab
,
0x1ff1459d
,
0xacab58fa
,
0x4b9303e3
,
0x2055fa30
,
0xadf66d76
,
0x889176cc
,
0xf5254c02
,
0x4ffcd7e5
,
0xc5d7cb2a
,
0x26804435
,
0xb58fa362
,
0xde495ab1
,
0x25671bba
,
0x45980eea
,
0x5de1c0fe
,
0xc302752f
,
0x8112f04c
,
0x8da39746
,
0x6bc6f9d3
,
0x03e75f8f
,
0x15959c92
,
0xbfeb7a6d
,
0x95da5952
,
0xd42d83be
,
0x58d32174
,
0x492969e0
,
0x8e44c8c9
,
0x756a89c2
,
0xf478798e
,
0x996b3e58
,
0x27dd71b9
,
0xbeb64fe1
,
0xf017ad88
,
0xc966ac20
,
0x7db43ace
,
0x63184adf
,
0xe582311a
,
0x97603351
,
0x62457f53
,
0xb1e07764
,
0xbb84ae6b
,
0xfe1ca081
,
0xf9942b08
,
0x70586848
,
0x8f19fd45
,
0x94876cde
,
0x52b7f87b
,
0xab23d373
,
0x72e2024b
,
0xe3578f1f
,
0x662aab55
,
0xb20728eb
,
0x2f03c2b5
,
0x869a7bc5
,
0xd3a50837
,
0x30f28728
,
0x23b2a5bf
,
0x02ba6a03
,
0xed5c8216
,
0x8a2b1ccf
,
0xa792b479
,
0xf3f0f207
,
0x4ea1e269
,
0x65cdf4da
,
0x06d5be05
,
0xd11f6234
,
0xc48afea6
,
0x349d532e
,
0xa2a055f3
,
0x0532e18a
,
0xa475ebf6
,
0x0b39ec83
,
0x40aaef60
,
0x5e069f71
,
0xbd51106e
,
0x3ef98a21
,
0x963d06dd
,
0xddae053e
,
0x4d46bde6
,
0x91b58d54
,
0x71055dc4
,
0x046fd406
,
0x60ff1550
,
0x1924fb98
,
0xd697e9bd
,
0x89cc4340
,
0x67779ed9
,
0xb0bd42e8
,
0x07888b89
,
0xe7385b19
,
0x79dbeec8
,
0xa1470a7c
,
0x7ce90f42
,
0xf8c91e84
,
0x00000000
,
0x09838680
,
0x3248ed2b
,
0x1eac7011
,
0x6c4e725a
,
0xfdfbff0e
,
0x0f563885
,
0x3d1ed5ae
,
0x3627392d
,
0x0a64d90f
,
0x6821a65c
,
0x9bd1545b
,
0x243a2e36
,
0x0cb1670a
,
0x930fe757
,
0xb4d296ee
,
0x1b9e919b
,
0x804fc5c0
,
0x61a220dc
,
0x5a694b77
,
0x1c161a12
,
0xe20aba93
,
0xc0e52aa0
,
0x3c43e022
,
0x121d171b
,
0x0e0b0d09
,
0xf2adc78b
,
0x2db9a8b6
,
0x14c8a91e
,
0x578519f1
,
0xaf4c0775
,
0xeebbdd99
,
0xa3fd607f
,
0xf79f2601
,
0x5cbcf572
,
0x44c53b66
,
0x5b347efb
,
0x8b762943
,
0xcbdcc623
,
0xb668fced
,
0xb863f1e4
,
0xd7cadc31
,
0x42108563
,
0x13402297
,
0x842011c6
,
0x857d244a
,
0xd2f83dbb
,
0xae1132f9
,
0xc76da129
,
0x1d4b2f9e
,
0xdcf330b2
,
0x0dec5286
,
0x77d0e3c1
,
0x2b6c16b3
,
0xa999b970
,
0x11fa4894
,
0x472264e9
,
0xa8c48cfc
,
0xa01a3ff0
,
0x56d82c7d
,
0x22ef9033
,
0x87c74e49
,
0xd9c1d138
,
0x8cfea2ca
,
0x98360bd4
,
0xa6cf81f5
,
0xa528de7a
,
0xda268eb7
,
0x3fa4bfad
,
0x2ce49d3a
,
0x500d9278
,
0x6a9bcc5f
,
0x5462467e
,
0xf6c2138d
,
0x90e8b8d8
,
0x2e5ef739
,
0x82f5afc3
,
0x9fbe805d
,
0x697c93d0
,
0x6fa92dd5
,
0xcfb31225
,
0xc83b99ac
,
0x10a77d18
,
0xe86e639c
,
0xdb7bbb3b
,
0xcd097826
,
0x6ef41859
,
0xec01b79a
,
0x83a89a4f
,
0xe6656e95
,
0xaa7ee6ff
,
0x2108cfbc
,
0xefe6e815
,
0xbad99be7
,
0x4ace366f
,
0xead4099f
,
0x29d67cb0
,
0x31afb2a4
,
0x2a31233f
,
0xc63094a5
,
0x35c066a2
,
0x7437bc4e
,
0xfca6ca82
,
0xe0b0d090
,
0x3315d8a7
,
0xf14a9804
,
0x41f7daec
,
0x7f0e50cd
,
0x172ff691
,
0x768dd64d
,
0x434db0ef
,
0xcc544daa
,
0xe4df0496
,
0x9ee3b5d1
,
0x4c1b886a
,
0xc1b81f2c
,
0x467f5165
,
0x9d04ea5e
,
0x015d358c
,
0xfa737487
,
0xfb2e410b
,
0xb35a1d67
,
0x9252d2db
,
0xe9335610
,
0x6d1347d6
,
0x9a8c61d7
,
0x377a0ca1
,
0x598e14f8
,
0xeb893c13
,
0xceee27a9
,
0xb735c961
,
0xe1ede51c
,
0x7a3cb147
,
0x9c59dfd2
,
0x553f73f2
,
0x1879ce14
,
0x73bf37c7
,
0x53eacdf7
,
0x5f5baafd
,
0xdf146f3d
,
0x7886db44
,
0xca81f3af
,
0xb93ec468
,
0x382c3424
,
0xc25f40a3
,
0x1672c31d
,
0xbc0c25e2
,
0x288b493c
,
0xff41950d
,
0x397101a8
,
0x08deb30c
,
0xd89ce4b4
,
0x6490c156
,
0x7b6184cb
,
0xd570b632
,
0x48745c6c
,
0xd04257b8
};
static
uint32_t
const
p_aes_decrypt
[
256
]
=
{
0x52000000
,
0x09000000
,
0x6a000000
,
0xd5000000
,
0x30000000
,
0x36000000
,
0xa5000000
,
0x38000000
,
0xbf000000
,
0x40000000
,
0xa3000000
,
0x9e000000
,
0x81000000
,
0xf3000000
,
0xd7000000
,
0xfb000000
,
0x7c000000
,
0xe3000000
,
0x39000000
,
0x82000000
,
0x9b000000
,
0x2f000000
,
0xff000000
,
0x87000000
,
0x34000000
,
0x8e000000
,
0x43000000
,
0x44000000
,
0xc4000000
,
0xde000000
,
0xe9000000
,
0xcb000000
,
0x54000000
,
0x7b000000
,
0x94000000
,
0x32000000
,
0xa6000000
,
0xc2000000
,
0x23000000
,
0x3d000000
,
0xee000000
,
0x4c000000
,
0x95000000
,
0x0b000000
,
0x42000000
,
0xfa000000
,
0xc3000000
,
0x4e000000
,
0x08000000
,
0x2e000000
,
0xa1000000
,
0x66000000
,
0x28000000
,
0xd9000000
,
0x24000000
,
0xb2000000
,
0x76000000
,
0x5b000000
,
0xa2000000
,
0x49000000
,
0x6d000000
,
0x8b000000
,
0xd1000000
,
0x25000000
,
0x72000000
,
0xf8000000
,
0xf6000000
,
0x64000000
,
0x86000000
,
0x68000000
,
0x98000000
,
0x16000000
,
0xd4000000
,
0xa4000000
,
0x5c000000
,
0xcc000000
,
0x5d000000
,
0x65000000
,
0xb6000000
,
0x92000000
,
0x6c000000
,
0x70000000
,
0x48000000
,
0x50000000
,
0xfd000000
,
0xed000000
,
0xb9000000
,
0xda000000
,
0x5e000000
,
0x15000000
,
0x46000000
,
0x57000000
,
0xa7000000
,
0x8d000000
,
0x9d000000
,
0x84000000
,
0x90000000
,
0xd8000000
,
0xab000000
,
0x00000000
,
0x8c000000
,
0xbc000000
,
0xd3000000
,
0x0a000000
,
0xf7000000
,
0xe4000000
,
0x58000000
,
0x05000000
,
0xb8000000
,
0xb3000000
,
0x45000000
,
0x06000000
,
0xd0000000
,
0x2c000000
,
0x1e000000
,
0x8f000000
,
0xca000000
,
0x3f000000
,
0x0f000000
,
0x02000000
,
0xc1000000
,
0xaf000000
,
0xbd000000
,
0x03000000
,
0x01000000
,
0x13000000
,
0x8a000000
,
0x6b000000
,
0x3a000000
,
0x91000000
,
0x11000000
,
0x41000000
,
0x4f000000
,
0x67000000
,
0xdc000000
,
0xea000000
,
0x97000000
,
0xf2000000
,
0xcf000000
,
0xce000000
,
0xf0000000
,
0xb4000000
,
0xe6000000
,
0x73000000
,
0x96000000
,
0xac000000
,
0x74000000
,
0x22000000
,
0xe7000000
,
0xad000000
,
0x35000000
,
0x85000000
,
0xe2000000
,
0xf9000000
,
0x37000000
,
0xe8000000
,
0x1c000000
,
0x75000000
,
0xdf000000
,
0x6e000000
,
0x47000000
,
0xf1000000
,
0x1a000000
,
0x71000000
,
0x1d000000
,
0x29000000
,
0xc5000000
,
0x89000000
,
0x6f000000
,
0xb7000000
,
0x62000000
,
0x0e000000
,
0xaa000000
,
0x18000000
,
0xbe000000
,
0x1b000000
,
0xfc000000
,
0x56000000
,
0x3e000000
,
0x4b000000
,
0xc6000000
,
0xd2000000
,
0x79000000
,
0x20000000
,
0x9a000000
,
0xdb000000
,
0xc0000000
,
0xfe000000
,
0x78000000
,
0xcd000000
,
0x5a000000
,
0xf4000000
,
0x1f000000
,
0xdd000000
,
0xa8000000
,
0x33000000
,
0x88000000
,
0x07000000
,
0xc7000000
,
0x31000000
,
0xb1000000
,
0x12000000
,
0x10000000
,
0x59000000
,
0x27000000
,
0x80000000
,
0xec000000
,
0x5f000000
,
0x60000000
,
0x51000000
,
0x7f000000
,
0xa9000000
,
0x19000000
,
0xb5000000
,
0x4a000000
,
0x0d000000
,
0x2d000000
,
0xe5000000
,
0x7a000000
,
0x9f000000
,
0x93000000
,
0xc9000000
,
0x9c000000
,
0xef000000
,
0xa0000000
,
0xe0000000
,
0x3b000000
,
0x4d000000
,
0xae000000
,
0x2a000000
,
0xf5000000
,
0xb0000000
,
0xc8000000
,
0xeb000000
,
0xbb000000
,
0x3c000000
,
0x83000000
,
0x53000000
,
0x99000000
,
0x61000000
,
0x17000000
,
0x2b000000
,
0x04000000
,
0x7e000000
,
0xba000000
,
0x77000000
,
0xd6000000
,
0x26000000
,
0xe1000000
,
0x69000000
,
0x14000000
,
0x63000000
,
0x55000000
,
0x21000000
,
0x0c000000
,
0x7d000000
};
/*****************************************************************************
* p_shuffle_xor, p_shuffle_sub, p_shuffle_add: iTMS drms v1
*****************************************************************************
* The following tables are used for the first version of the iTMS drms key
* scrambling algorithm.
*****************************************************************************/
static
uint16_t
const
p_shuffle_xor
[
256
]
=
{
0x00d1
,
0x0315
,
0x1a32
,
0x19ec
,
0x1bbb
,
0x1d6f
,
0x14fe
,
0x0e9e
,
0x029e
,
0x1b8f
,
0x0b70
,
0x033a
,
0x188e
,
0x1d18
,
0x0bd8
,
0x0edb
,
0x0c64
,
0x1c2b
,
0x149c
,
0x047b
,
0x1064
,
0x1c7c
,
0x118d
,
0x1355
,
0x0ae5
,
0x0f18
,
0x016f
,
0x17d6
,
0x1595
,
0x0084
,
0x0616
,
0x1ccd
,
0x1d94
,
0x0618
,
0x182c
,
0x195b
,
0x196d
,
0x0394
,
0x07db
,
0x0287
,
0x1636
,
0x0b81
,
0x1519
,
0x0df9
,
0x1ba3
,
0x1cc3
,
0x0ee2
,
0x1434
,
0x1457
,
0x0ced
,
0x0f7d
,
0x0d7b
,
0x0b9e
,
0x0d13
,
0x13d7
,
0x18d0
,
0x1259
,
0x1977
,
0x0606
,
0x1e80
,
0x05f2
,
0x06b8
,
0x1f07
,
0x1365
,
0x0334
,
0x0e30
,
0x195f
,
0x15f1
,
0x058e
,
0x0aa8
,
0x045a
,
0x0465
,
0x0b3e
,
0x071e
,
0x0a36
,
0x105c
,
0x01ac
,
0x1a1e
,
0x04e4
,
0x056b
,
0x12bf
,
0x0da2
,
0x0b41
,
0x0eaf
,
0x034f
,
0x0181
,
0x04e2
,
0x002b
,
0x12e6
,
0x01be
,
0x10e8
,
0x128f
,
0x0eb2
,
0x1369
,
0x05be
,
0x1a59
,
0x117e
,
0x047c
,
0x1e86
,
0x056a
,
0x0da7
,
0x0d61
,
0x03fc
,
0x1e6e
,
0x1d0c
,
0x1e6d
,
0x14bf
,
0x0c50
,
0x063a
,
0x1b47
,
0x17ae
,
0x1321
,
0x041b
,
0x0a24
,
0x0d4d
,
0x1f2b
,
0x1cb6
,
0x1bed
,
0x1549
,
0x03a7
,
0x0254
,
0x006c
,
0x0c9e
,
0x0f73
,
0x006c
,
0x0008
,
0x11f9
,
0x0dd5
,
0x0bcf
,
0x0af9
,
0x1dfe
,
0x0341
,
0x0e49
,
0x0d38
,
0x17cb
,
0x1513
,
0x0e96
,
0x00ed
,
0x0556
,
0x1b28
,
0x100c
,
0x19d8
,
0x14fa
,
0x028c
,
0x1c60
,
0x1232
,
0x13d3
,
0x0d00
,
0x1534
,
0x192c
,
0x14b5
,
0x1cf2
,
0x0504
,
0x0b5b
,
0x1ecf
,
0x0423
,
0x183b
,
0x06b0
,
0x169e
,
0x1066
,
0x04cb
,
0x08a2
,
0x1b4a
,
0x1254
,
0x198d
,
0x1044
,
0x0236
,
0x1bd8
,
0x18a1
,
0x03ff
,
0x1a0d
,
0x0277
,
0x0c2d
,
0x17c9
,
0x007c
,
0x116e
,
0x048a
,
0x1eaf
,
0x0922
,
0x0c45
,
0x0766
,
0x1e5f
,
0x1a28
,
0x0120
,
0x1c15
,
0x034c
,
0x0508
,
0x0e73
,
0x0879
,
0x0441
,
0x09ae
,
0x132f
,
0x14fe
,
0x0413
,
0x0a9d
,
0x1727
,
0x01d7
,
0x1a2b
,
0x0474
,
0x18f0
,
0x1f3b
,
0x14f5
,
0x1071
,
0x0895
,
0x1071
,
0x18ff
,
0x18e3
,
0x0eb9
,
0x0ba9
,
0x0961
,
0x1599
,
0x019e
,
0x1d12
,
0x1baa
,
0x1e94
,
0x1921
,
0x14dc
,
0x124e
,
0x0a25
,
0x03ab
,
0x1cc0
,
0x1ebb
,
0x0b4b
,
0x16e5
,
0x11ea
,
0x0d78
,
0x1bb3
,
0x1ba7
,
0x1510
,
0x1b7b
,
0x0c64
,
0x1995
,
0x1a58
,
0x1651
,
0x1964
,
0x147a
,
0x15f2
,
0x11bb
,
0x1654
,
0x166e
,
0x0ea9
,
0x1de1
,
0x1443
,
0x13c5
,
0x00e1
,
0x0b2f
,
0x0b6f
,
0x0a37
,
0x18ac
,
0x08e6
,
0x06f0
,
0x136e
,
0x0853
,
0x0b2e
,
0x0813
,
0x10d6
};
static
uint16_t
const
p_shuffle_sub
[
256
]
=
{
0x067a
,
0x0c7d
,
0x0b4f
,
0x127d
,
0x0bd6
,
0x04ac
,
0x16e0
,
0x1730
,
0x0587
,
0x0afb
,
0x1ac3
,
0x0120
,
0x14b5
,
0x0f67
,
0x11de
,
0x0961
,
0x1127
,
0x1a68
,
0x07f0
,
0x17d0
,
0x1a6f
,
0x1f3b
,
0x01ef
,
0x0919
,
0x131e
,
0x0f90
,
0x19e9
,
0x18a8
,
0x0cb2
,
0x1ad0
,
0x0c66
,
0x0378
,
0x03b0
,
0x01be
,
0x1866
,
0x1159
,
0x197c
,
0x1105
,
0x010b
,
0x0353
,
0x1abb
,
0x09a6
,
0x028a
,
0x1bad
,
0x1b20
,
0x0455
,
0x0f57
,
0x0588
,
0x1491
,
0x0a1d
,
0x0f04
,
0x0650
,
0x191e
,
0x1e0e
,
0x174b
,
0x016b
,
0x051f
,
0x0532
,
0x00df
,
0x1aea
,
0x0005
,
0x0e1b
,
0x0ff6
,
0x08d8
,
0x14b4
,
0x086a
,
0x0c20
,
0x0149
,
0x1971
,
0x0f26
,
0x1852
,
0x017d
,
0x1228
,
0x0352
,
0x0a44
,
0x1330
,
0x18df
,
0x1e38
,
0x01bc
,
0x0bac
,
0x1a48
,
0x021f
,
0x02f7
,
0x0c31
,
0x0bc4
,
0x1e75
,
0x105c
,
0x13e3
,
0x0b20
,
0x03a1
,
0x1af3
,
0x1a36
,
0x0e34
,
0x181f
,
0x09bd
,
0x122b
,
0x0ee0
,
0x163b
,
0x0be7
,
0x103d
,
0x1075
,
0x1e9d
,
0x02af
,
0x0ba2
,
0x1daa
,
0x0cf1
,
0x04b6
,
0x0598
,
0x06a1
,
0x0d33
,
0x1cfe
,
0x04ee
,
0x1bad
,
0x07c8
,
0x1a48
,
0x05e6
,
0x031f
,
0x0e0a
,
0x0326
,
0x1650
,
0x0526
,
0x0b4e
,
0x08fc
,
0x0e4d
,
0x0832
,
0x06ea
,
0x09bf
,
0x0993
,
0x09eb
,
0x0f31
,
0x071b
,
0x14d5
,
0x11ca
,
0x0722
,
0x120d
,
0x014c
,
0x1993
,
0x0ae4
,
0x1ccb
,
0x04e9
,
0x0aee
,
0x1708
,
0x0c3d
,
0x12f2
,
0x1a19
,
0x07c1
,
0x05a7
,
0x0744
,
0x1606
,
0x1a9b
,
0x042d
,
0x1bfc
,
0x1841
,
0x0c3c
,
0x0ffe
,
0x1ab1
,
0x1416
,
0x18a9
,
0x0320
,
0x1ec2
,
0x0ae7
,
0x11c6
,
0x124a
,
0x11df
,
0x0f81
,
0x06cf
,
0x0ed9
,
0x0253
,
0x1d2b
,
0x0349
,
0x0805
,
0x08b3
,
0x1052
,
0x12cf
,
0x0a44
,
0x0ea6
,
0x03bf
,
0x1d90
,
0x0ef8
,
0x0657
,
0x156d
,
0x0405
,
0x10be
,
0x091f
,
0x1c82
,
0x1725
,
0x19ef
,
0x0b8c
,
0x04d9
,
0x02c7
,
0x025a
,
0x1b89
,
0x0f5c
,
0x013d
,
0x02f7
,
0x12e3
,
0x0bc5
,
0x1b56
,
0x0848
,
0x0239
,
0x0fcf
,
0x03a4
,
0x092d
,
0x1354
,
0x1d83
,
0x01bd
,
0x071a
,
0x0af1
,
0x0875
,
0x0793
,
0x1b41
,
0x1782
,
0x0def
,
0x1d20
,
0x13be
,
0x0095
,
0x1650
,
0x19d4
,
0x0de3
,
0x0980
,
0x18f2
,
0x0ca3
,
0x0098
,
0x149a
,
0x0b81
,
0x0ad2
,
0x1bba
,
0x1a02
,
0x027b
,
0x1906
,
0x07f5
,
0x1cae
,
0x0c3f
,
0x02f6
,
0x1298
,
0x175e
,
0x15b2
,
0x13d8
,
0x14cc
,
0x161a
,
0x0a42
,
0x15f3
,
0x0870
,
0x1c1d
,
0x1203
,
0x18b1
,
0x1738
,
0x1954
,
0x1143
,
0x1ae8
,
0x1d9d
,
0x155b
,
0x11e8
,
0x0ed9
,
0x06f7
,
0x04ca
};
static
uint16_t
const
p_shuffle_add
[
256
]
=
{
0x0706
,
0x175a
,
0x0def
,
0x1e72
,
0x0297
,
0x1b0e
,
0x1d5a
,
0x15b8
,
0x13e2
,
0x1347
,
0x10c6
,
0x0b4f
,
0x0629
,
0x0a75
,
0x0a9b
,
0x0f55
,
0x1a69
,
0x09bf
,
0x0ba6
,
0x1582
,
0x1086
,
0x1921
,
0x01cb
,
0x1c6a
,
0x0ff5
,
0x00f7
,
0x0a67
,
0x0a1e
,
0x1838
,
0x0196
,
0x10d6
,
0x0c7a
,
0x180e
,
0x038d
,
0x1add
,
0x0684
,
0x154a
,
0x0ab0
,
0x18a4
,
0x0d73
,
0x1641
,
0x0ec6
,
0x09f1
,
0x1a62
,
0x0414
,
0x162a
,
0x194e
,
0x1ec9
,
0x022f
,
0x0296
,
0x1104
,
0x14fc
,
0x096c
,
0x1d02
,
0x09bd
,
0x027c
,
0x080e
,
0x1324
,
0x128c
,
0x0dc1
,
0x00b9
,
0x17f2
,
0x0cbc
,
0x0f97
,
0x1b93
,
0x1c3c
,
0x0415
,
0x0395
,
0x0c7a
,
0x06cc
,
0x0d4b
,
0x16e2
,
0x04a2
,
0x0dab
,
0x1228
,
0x012b
,
0x0896
,
0x0012
,
0x1cd6
,
0x1dac
,
0x080d
,
0x0446
,
0x047a
,
0x00ad
,
0x029e
,
0x0686
,
0x17c3
,
0x1466
,
0x0d16
,
0x1896
,
0x076e
,
0x00cd
,
0x17dc
,
0x1e9f
,
0x1a7c
,
0x02bb
,
0x0d06
,
0x112b
,
0x14cb
,
0x0a03
,
0x1541
,
0x1290
,
0x0f6d
,
0x1503
,
0x084b
,
0x0382
,
0x1a3f
,
0x0371
,
0x1977
,
0x0b67
,
0x0cad
,
0x1df8
,
0x1ce3
,
0x1306
,
0x13f8
,
0x1163
,
0x1b0b
,
0x00bd
,
0x0bf0
,
0x1a4f
,
0x16f7
,
0x0b4f
,
0x0cf8
,
0x1254
,
0x0541
,
0x100d
,
0x0296
,
0x0410
,
0x1a2b
,
0x1169
,
0x17d9
,
0x0819
,
0x03d6
,
0x0d03
,
0x194d
,
0x184a
,
0x07ca
,
0x1989
,
0x0fad
,
0x011c
,
0x1c71
,
0x0ef6
,
0x0dc8
,
0x0f2f
,
0x0fa5
,
0x11be
,
0x0f3b
,
0x1d52
,
0x0de2
,
0x016e
,
0x1ad1
,
0x0c4a
,
0x1bc2
,
0x0ac9
,
0x1485
,
0x1bee
,
0x0949
,
0x1a79
,
0x1894
,
0x12bb
,
0x17b6
,
0x14f5
,
0x16b1
,
0x142c
,
0x1301
,
0x03ef
,
0x16ff
,
0x0d37
,
0x0d78
,
0x01ff
,
0x00d6
,
0x1053
,
0x1a2a
,
0x0f61
,
0x1352
,
0x0c7f
,
0x137f
,
0x09c4
,
0x1d96
,
0x021d
,
0x1037
,
0x1b19
,
0x10ef
,
0x14e4
,
0x02a0
,
0x0236
,
0x0a5d
,
0x1519
,
0x141c
,
0x1399
,
0x007e
,
0x1e74
,
0x0941
,
0x1b3c
,
0x0062
,
0x0371
,
0x09ad
,
0x08e8
,
0x0a24
,
0x0b97
,
0x1ed2
,
0x0889
,
0x136b
,
0x0006
,
0x1c4c
,
0x0444
,
0x06f8
,
0x0dfb
,
0x1d0f
,
0x198d
,
0x0700
,
0x0afc
,
0x1781
,
0x12f3
,
0x10da
,
0x1f19
,
0x1055
,
0x0dc9
,
0x1860
,
0x012b
,
0x05bf
,
0x082d
,
0x0c17
,
0x1941
,
0x0359
,
0x1232
,
0x104c
,
0x0762
,
0x0897
,
0x1d6c
,
0x030f
,
0x1a36
,
0x16b0
,
0x094d
,
0x1782
,
0x036f
,
0x0eea
,
0x06e6
,
0x0d00
,
0x0187
,
0x17e2
,
0x05e5
,
0x19fa
,
0x1950
,
0x146a
,
0x0b2a
,
0x0512
,
0x0ee0
,
0x1e27
,
0x112d
,
0x1df0
,
0x0b13
,
0x0378
,
0x1dd0
,
0x00c1
,
0x01e6
};
modules/demux/mp4/libmp4.c
View file @
34acedc6
...
...
@@ -32,7 +32,6 @@
#endif
#include "libmp4.h"
#include "drms.h"
#include <math.h>
/*****************************************************************************
...
...
@@ -1671,13 +1670,8 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
if
(
p_box
->
i_type
==
ATOM_drms
)
{
char
*
home
=
config_GetUserDir
(
VLC_HOME_DIR
);
if
(
home
!=
NULL
)
{
p_box
->
data
.
p_sample_soun
->
p_drms
=
drms_alloc
(
home
);
if
(
p_box
->
data
.
p_sample_soun
->
p_drms
==
NULL
)
msg_Err
(
p_stream
,
"drms_alloc() failed"
);
}
msg_Warn
(
p_stream
,
"DRM protected streams are not supported."
);
MP4_READBOX_EXIT
(
0
);
}
if
(
p_box
->
i_type
==
ATOM_samr
||
p_box
->
i_type
==
ATOM_sawb
)
...
...
@@ -1704,14 +1698,6 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
static
void
MP4_FreeBox_sample_soun
(
MP4_Box_t
*
p_box
)
{
FREENULL
(
p_box
->
data
.
p_sample_soun
->
p_qt_description
);
if
(
p_box
->
i_type
==
ATOM_drms
)
{
if
(
p_box
->
data
.
p_sample_soun
->
p_drms
)
{
drms_free
(
p_box
->
data
.
p_sample_soun
->
p_drms
);
}
}
}
...
...
@@ -1770,13 +1756,8 @@ int MP4_ReadBox_sample_vide( stream_t *p_stream, MP4_Box_t *p_box )
if
(
p_box
->
i_type
==
ATOM_drmi
)
{
char
*
home
=
config_GetUserDir
(
VLC_HOME_DIR
);
if
(
home
!=
NULL
)
{
p_box
->
data
.
p_sample_vide
->
p_drms
=
drms_alloc
(
home
);
if
(
p_box
->
data
.
p_sample_vide
->
p_drms
==
NULL
)
msg_Err
(
p_stream
,
"drms_alloc() failed"
);
}
msg_Warn
(
p_stream
,
"DRM protected streams are not supported."
);
MP4_READBOX_EXIT
(
0
);
}
MP4_ReadBoxContainerRaw
(
p_stream
,
p_box
);
...
...
@@ -1795,14 +1776,6 @@ int MP4_ReadBox_sample_vide( stream_t *p_stream, MP4_Box_t *p_box )
void
MP4_FreeBox_sample_vide
(
MP4_Box_t
*
p_box
)
{
FREENULL
(
p_box
->
data
.
p_sample_vide
->
p_qt_image_description
);
if
(
p_box
->
i_type
==
ATOM_drmi
)
{
if
(
p_box
->
data
.
p_sample_vide
->
p_drms
)
{
drms_free
(
p_box
->
data
.
p_sample_vide
->
p_drms
);
}
}
}
static
int
MP4_ReadBox_sample_mp4s
(
stream_t
*
p_stream
,
MP4_Box_t
*
p_box
)
...
...
@@ -2593,56 +2566,11 @@ static int MP4_ReadBox_skcr( stream_t *p_stream, MP4_Box_t *p_box )
static
int
MP4_ReadBox_drms
(
stream_t
*
p_stream
,
MP4_Box_t
*
p_box
)
{
MP4_Box_t
*
p_drms_box
=
p_box
;
void
*
p_drms
=
NULL
;
MP4_READBOX_ENTER
(
uint8_t
);
do
{
p_drms_box
=
p_drms_box
->
p_father
;
}
while
(
p_drms_box
&&
p_drms_box
->
i_type
!=
ATOM_drms
&&
p_drms_box
->
i_type
!=
ATOM_drmi
);
if
(
p_drms_box
&&
p_drms_box
->
i_type
==
ATOM_drms
)
p_drms
=
p_drms_box
->
data
.
p_sample_soun
->
p_drms
;
else
if
(
p_drms_box
&&
p_drms_box
->
i_type
==
ATOM_drmi
)
p_drms
=
p_drms_box
->
data
.
p_sample_vide
->
p_drms
;
if
(
p_drms_box
&&
p_drms
)
{
int
i_ret
=
drms_init
(
p_drms
,
p_box
->
i_type
,
p_peek
,
i_read
);
if
(
i_ret
)
{
const
char
*
psz_error
;
switch
(
i_ret
)
{
case
-
1
:
psz_error
=
"unimplemented"
;
break
;
case
-
2
:
psz_error
=
"invalid argument"
;
break
;
case
-
3
:
psz_error
=
"could not get system key"
;
break
;
case
-
4
:
psz_error
=
"could not get SCI data"
;
break
;
case
-
5
:
psz_error
=
"no user key found in SCI data"
;
break
;
case
-
6
:
psz_error
=
"invalid user key"
;
break
;
default:
psz_error
=
"unknown error"
;
break
;
}
if
MP4_BOX_TYPE_ASCII
()
msg_Err
(
p_stream
,
"drms_init(%4.4s) failed (%s)"
,
(
char
*
)
&
p_box
->
i_type
,
psz_error
);
else
msg_Err
(
p_stream
,
"drms_init(c%3.3s) failed (%s)"
,
(
char
*
)
&
p_box
->
i_type
+
1
,
psz_error
);
drms_free
(
p_drms
);
if
(
p_drms_box
->
i_type
==
ATOM_drms
)
p_drms_box
->
data
.
p_sample_soun
->
p_drms
=
NULL
;
else
if
(
p_drms_box
->
i_type
==
ATOM_drmi
)
p_drms_box
->
data
.
p_sample_vide
->
p_drms
=
NULL
;
}
}
MP4_READBOX_EXIT
(
1
);
/* ATOMs 'user', 'key', 'iviv', and 'priv' will be skipped,
* so unless data decrypt itself by magic, there will be no playback,
* but we never know... */
msg_Warn
(
p_stream
,
"DRM protected streams are not supported."
);
return
1
;
}
static
int
MP4_ReadBox_name
(
stream_t
*
p_stream
,
MP4_Box_t
*
p_box
)
...
...
modules/demux/mp4/libmp4.h
View file @
34acedc6
...
...
@@ -487,8 +487,6 @@ typedef struct MP4_Box_data_sample_soun_s
int
i_qt_description
;
uint8_t
*
p_qt_description
;
void
*
p_drms
;
}
MP4_Box_data_sample_soun_t
;
typedef
struct
MP4_Box_data_sample_vide_s
...
...
@@ -521,8 +519,6 @@ typedef struct MP4_Box_data_sample_vide_s
int
i_qt_image_description
;
uint8_t
*
p_qt_image_description
;
void
*
p_drms
;
}
MP4_Box_data_sample_vide_t
;
#define MP4_TEXT_DISPLAY_FLAG_DONT_DISPLAY (1<<0)
...
...
modules/demux/mp4/mp4.c
View file @
34acedc6
...
...
@@ -37,7 +37,6 @@
#include <vlc_input.h>
#include "libmp4.h"
#include "drms.h"
#include "id3genres.h"
/* for ATOM_gnre */
/*****************************************************************************
...
...
@@ -135,8 +134,6 @@ typedef struct
MP4_Box_t
*
p_stsd
;
/* will contain all data to initialize decoder */
MP4_Box_t
*
p_sample
;
/* point on actual sdsd */
bool
b_drms
;
void
*
p_drms
;
MP4_Box_t
*
p_skcr
;
}
mp4_track_t
;
...
...
@@ -684,27 +681,6 @@ static int Demux( demux_t *p_demux )
break
;
}
if
(
tk
->
b_drms
&&
tk
->
p_drms
)
{
if
(
tk
->
p_skcr
)
{
uint32_t
p_key
[
4
];
drms_get_p_key
(
tk
->
p_drms
,
p_key
);
for
(
size_t
i_pos
=
tk
->
p_skcr
->
data
.
p_skcr
->
i_init
;
i_pos
<
p_block
->
i_buffer
;
)
{
int
n
=
__MIN
(
tk
->
p_skcr
->
data
.
p_skcr
->
i_encr
,
p_block
->
i_buffer
-
i_pos
);
drms_decrypt
(
tk
->
p_drms
,
(
uint32_t
*
)
&
p_block
->
p_buffer
[
i_pos
],
n
,
p_key
);
i_pos
+=
n
;
i_pos
+=
__MIN
(
tk
->
p_skcr
->
data
.
p_skcr
->
i_decr
,
p_block
->
i_buffer
-
i_pos
);
}
}
else
{
drms_decrypt
(
tk
->
p_drms
,
(
uint32_t
*
)
p_block
->
p_buffer
,
p_block
->
i_buffer
,
NULL
);
}
}
else
if
(
tk
->
fmt
.
i_cat
==
SPU_ES
)
{
if
(
tk
->
fmt
.
i_codec
==
VLC_FOURCC
(
's'
,
'u'
,
'b'
,
't'
)
&&
...
...
@@ -745,8 +721,7 @@ static int Demux( demux_t *p_demux )
else
p_block
->
i_pts
=
VLC_TS_INVALID
;
if
(
!
tk
->
b_drms
||
(
tk
->
b_drms
&&
tk
->
p_drms
)
)
es_out_Send
(
p_demux
->
out
,
tk
->
p_es
,
p_block
);
es_out_Send
(
p_demux
->
out
,
tk
->
p_es
,
p_block
);
}
/* Next sample */
...
...
@@ -2273,8 +2248,6 @@ static void MP4_TrackCreate( demux_t *p_demux, mp4_track_t *p_track,
MP4_Box_t
*
p_vmhd
;
MP4_Box_t
*
p_smhd
;
MP4_Box_t
*
p_drms
;
unsigned
int
i
;
char
language
[
4
];
...
...
@@ -2396,22 +2369,6 @@ static void MP4_TrackCreate( demux_t *p_demux, mp4_track_t *p_track,
return
;
}
p_drms
=
MP4_BoxGet
(
p_track
->
p_stsd
,
"drms"
);
p_track
->
b_drms
=
p_drms
!=
NULL
;
p_track
->
p_drms
=
p_track
->
b_drms
?
p_drms
->
data
.
p_sample_soun
->
p_drms
:
NULL
;
if
(
!
p_drms
)
{
p_drms
=
MP4_BoxGet
(
p_track
->
p_stsd
,
"drmi"
);
p_track
->
b_drms
=
p_drms
!=
NULL
;
p_track
->
p_drms
=
p_track
->
b_drms
?
p_drms
->
data
.
p_sample_vide
->
p_drms
:
NULL
;
}
if
(
p_drms
)
p_track
->
p_skcr
=
MP4_BoxGet
(
p_drms
,
"sinf/skcr"
);
/* Set language */
if
(
*
language
&&
strcmp
(
language
,
"```"
)
&&
strcmp
(
language
,
"und"
)
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment