Mercurial > mplayer.hg
annotate libmpdvdkit2/css.c @ 18049:77a3b0d11ca5
Limit the number of entires to the amount that does fit into the chunk.
the function need rewrite as it assumes quite many things that are not guaranteed by the specifications.
author | iive |
---|---|
date | Thu, 06 Apr 2006 20:04:02 +0000 |
parents | 2ab52c9b72b9 |
children | 0783dd397f74 |
rev | line source |
---|---|
7027 | 1 /***************************************************************************** |
2 * css.c: Functions for DVD authentication and descrambling | |
3 ***************************************************************************** | |
16630 | 4 * Copyright (C) 1999-2003 VideoLAN |
16631 | 5 * |
6 * Modified for use with MPlayer, changes contained in libdvdcss_changes.diff. | |
7 * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ | |
7027 | 8 * $Id$ |
9 * | |
16630 | 10 * Authors: Stéphane Borel <stef@via.ecp.fr> |
11 * Håkan Hjort <d95hjort@dtek.chalmers.se> | |
7027 | 12 * |
13 * based on: | |
14 * - css-auth by Derek Fawcus <derek@spider.com> | |
15 * - DVD CSS ioctls example program by Andrew T. Veliath <andrewtv@usa.net> | |
16 * - The Divide and conquer attack by Frank A. Stevenson <frank@funcom.com> | |
16630 | 17 * (see http://www-2.cs.cmu.edu/~dst/DeCSS/FrankStevenson/index.html) |
7027 | 18 * - DeCSSPlus by Ethan Hawke |
19 * - DecVOB | |
20 * see http://www.lemuria.org/DeCSS/ by Tom Vogt for more information. | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
21 * |
7027 | 22 * This program is free software; you can redistribute it and/or modify |
23 * it under the terms of the GNU General Public License as published by | |
24 * the Free Software Foundation; either version 2 of the License, or | |
25 * (at your option) any later version. | |
26 * | |
27 * This program is distributed in the hope that it will be useful, | |
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
30 * GNU General Public License for more details. | |
31 * | |
32 * You should have received a copy of the GNU General Public License | |
33 * along with this program; if not, write to the Free Software | |
34 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. | |
35 *****************************************************************************/ | |
36 | |
37 /***************************************************************************** | |
38 * Preamble | |
39 *****************************************************************************/ | |
40 #include "config.h" | |
41 | |
42 #include <stdio.h> | |
43 #include <stdlib.h> | |
44 #include <string.h> | |
7032 | 45 #include <sys/types.h> |
46 #include <sys/stat.h> | |
16714
2ab52c9b72b9
Replace unconditional #defines by build system trickery.
diego
parents:
16631
diff
changeset
|
47 #ifdef HAVE_SYS_PARAM_H |
2ab52c9b72b9
Replace unconditional #defines by build system trickery.
diego
parents:
16631
diff
changeset
|
48 # include <sys/param.h> |
2ab52c9b72b9
Replace unconditional #defines by build system trickery.
diego
parents:
16631
diff
changeset
|
49 #endif |
2ab52c9b72b9
Replace unconditional #defines by build system trickery.
diego
parents:
16631
diff
changeset
|
50 #ifdef HAVE_UNISTD_H |
16630 | 51 # include <unistd.h> |
16714
2ab52c9b72b9
Replace unconditional #defines by build system trickery.
diego
parents:
16631
diff
changeset
|
52 #endif |
7032 | 53 #include <fcntl.h> |
16714
2ab52c9b72b9
Replace unconditional #defines by build system trickery.
diego
parents:
16631
diff
changeset
|
54 |
2ab52c9b72b9
Replace unconditional #defines by build system trickery.
diego
parents:
16631
diff
changeset
|
55 #ifdef HAVE_LIMITS_H |
16630 | 56 # include <limits.h> |
16714
2ab52c9b72b9
Replace unconditional #defines by build system trickery.
diego
parents:
16631
diff
changeset
|
57 #endif |
7027 | 58 |
7033 | 59 #include "dvdcss.h" |
7027 | 60 |
61 #include "common.h" | |
62 #include "css.h" | |
63 #include "libdvdcss.h" | |
64 #include "csstables.h" | |
65 #include "ioctl.h" | |
66 #include "device.h" | |
67 | |
68 /***************************************************************************** | |
69 * Local prototypes | |
70 *****************************************************************************/ | |
16630 | 71 static void PrintKey ( dvdcss_t, char *, uint8_t const * ); |
72 | |
7027 | 73 static int GetBusKey ( dvdcss_t ); |
74 static int GetASF ( dvdcss_t ); | |
75 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
76 static void CryptKey ( int, int, uint8_t const *, uint8_t * ); |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
77 static void DecryptKey ( uint8_t, |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
78 uint8_t const *, uint8_t const *, uint8_t * ); |
7027 | 79 |
16630 | 80 static int DecryptDiscKey ( dvdcss_t, uint8_t const *, dvd_key_t ); |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
81 static int CrackDiscKey ( dvdcss_t, uint8_t * ); |
7027 | 82 |
83 static void DecryptTitleKey ( dvd_key_t, dvd_key_t ); | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
84 static int RecoverTitleKey ( int, uint8_t const *, |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
85 uint8_t const *, uint8_t const *, uint8_t * ); |
7027 | 86 static int CrackTitleKey ( dvdcss_t, int, int, dvd_key_t ); |
87 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
88 static int AttackPattern ( uint8_t const[], int, uint8_t * ); |
7027 | 89 #if 0 |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
90 static int AttackPadding ( uint8_t const[], int, uint8_t * ); |
7027 | 91 #endif |
92 | |
93 /***************************************************************************** | |
94 * _dvdcss_test: check if the disc is encrypted or not | |
95 *****************************************************************************/ | |
96 int _dvdcss_test( dvdcss_t dvdcss ) | |
97 { | |
98 int i_ret, i_copyright; | |
99 | |
100 i_ret = ioctl_ReadCopyright( dvdcss->i_fd, 0 /* i_layer */, &i_copyright ); | |
101 | |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
102 #ifdef WIN32 |
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
103 if( i_ret < 0 ) |
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
104 { |
16630 | 105 /* Maybe we didn't have enough privileges to read the copyright |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
106 * (see ioctl_ReadCopyright comments). |
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
107 * Apparently, on unencrypted DVDs _dvdcss_disckey() always fails, so |
16630 | 108 * we can check this as a workaround. */ |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
109 i_ret = 0; |
16630 | 110 i_copyright = 1; |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
111 if( _dvdcss_disckey( dvdcss ) < 0 ) |
16630 | 112 { |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
113 i_copyright = 0; |
16630 | 114 } |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
115 } |
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
116 #endif |
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
117 |
7027 | 118 if( i_ret < 0 ) |
119 { | |
120 /* Since it's the first ioctl we try to issue, we add a notice */ | |
16630 | 121 print_error( dvdcss, "css error: ioctl_ReadCopyright failed, " |
122 "make sure there is a DVD in the drive, and that " | |
123 "you have used the correct device node." ); | |
7027 | 124 |
125 return i_ret; | |
126 } | |
127 | |
128 return i_copyright; | |
129 } | |
130 | |
131 /***************************************************************************** | |
132 * _dvdcss_title: crack or decrypt the current title key if needed | |
133 ***************************************************************************** | |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
134 * This function should only be called by dvdcss->pf_seek and should eventually |
7027 | 135 * not be external if possible. |
136 *****************************************************************************/ | |
137 int _dvdcss_title ( dvdcss_t dvdcss, int i_block ) | |
138 { | |
139 dvd_title_t *p_title; | |
140 dvd_title_t *p_newtitle; | |
141 dvd_key_t p_title_key; | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
142 int i_fd, i_ret = -1, b_cache = 0; |
7027 | 143 |
144 if( ! dvdcss->b_scrambled ) | |
145 { | |
146 return 0; | |
147 } | |
148 | |
149 /* Check if we've already cracked this key */ | |
150 p_title = dvdcss->p_titles; | |
151 while( p_title != NULL | |
152 && p_title->p_next != NULL | |
153 && p_title->p_next->i_startlb <= i_block ) | |
154 { | |
155 p_title = p_title->p_next; | |
156 } | |
157 | |
158 if( p_title != NULL | |
159 && p_title->i_startlb == i_block ) | |
160 { | |
161 /* We've already cracked this key, nothing to do */ | |
162 memcpy( dvdcss->css.p_title_key, p_title->p_key, sizeof(dvd_key_t) ); | |
163 return 0; | |
164 } | |
165 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
166 /* Check whether the key is in our disk cache */ |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
167 if( dvdcss->psz_cachefile[0] ) |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
168 { |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
169 /* XXX: be careful, we use sprintf and not snprintf */ |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
170 sprintf( dvdcss->psz_block, "%.10x", i_block ); |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
171 i_fd = open( dvdcss->psz_cachefile, O_RDONLY ); |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
172 b_cache = 1; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
173 |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
174 if( i_fd >= 0 ) |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
175 { |
16630 | 176 unsigned char psz_key[KEY_SIZE * 3]; |
177 unsigned int k0, k1, k2, k3, k4; | |
178 | |
179 psz_key[KEY_SIZE * 3 - 1] = '\0'; | |
180 | |
181 if( read( i_fd, psz_key, KEY_SIZE * 3 - 1 ) == KEY_SIZE * 3 - 1 | |
182 && sscanf( psz_key, "%x:%x:%x:%x:%x", | |
183 &k0, &k1, &k2, &k3, &k4 ) == 5 ) | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
184 { |
16630 | 185 p_title_key[0] = k0; |
186 p_title_key[1] = k1; | |
187 p_title_key[2] = k2; | |
188 p_title_key[3] = k3; | |
189 p_title_key[4] = k4; | |
190 PrintKey( dvdcss, "title key found in cache ", p_title_key ); | |
191 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
192 /* Don't try to save it again */ |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
193 b_cache = 0; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
194 i_ret = 1; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
195 } |
16630 | 196 |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
197 close( i_fd ); |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
198 } |
7032 | 199 } |
200 | |
7027 | 201 /* Crack or decrypt CSS title key for current VTS */ |
202 if( i_ret < 0 ) | |
203 { | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
204 i_ret = _dvdcss_titlekey( dvdcss, i_block, p_title_key ); |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
205 |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
206 if( i_ret < 0 ) |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
207 { |
16630 | 208 print_error( dvdcss, "fatal error in vts css key" ); |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
209 return i_ret; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
210 } |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
211 |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
212 if( i_ret == 0 ) |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
213 { |
16630 | 214 print_debug( dvdcss, "unencrypted title" ); |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
215 /* We cache this anyway, so we don't need to check again. */ |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
216 } |
7027 | 217 } |
218 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
219 /* Key is valid, we store it on disk. */ |
16630 | 220 if( dvdcss->psz_cachefile[0] && b_cache ) |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
221 { |
16630 | 222 i_fd = open( dvdcss->psz_cachefile, O_RDWR|O_CREAT, 0644 ); |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
223 if( i_fd >= 0 ) |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
224 { |
16630 | 225 unsigned char psz_key[KEY_SIZE * 3 + 2]; |
226 | |
227 sprintf( psz_key, "%02x:%02x:%02x:%02x:%02x\r\n", | |
228 p_title_key[0], p_title_key[1], p_title_key[2], | |
229 p_title_key[3], p_title_key[4] ); | |
230 | |
231 write( i_fd, psz_key, KEY_SIZE * 3 + 1 ); | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
232 close( i_fd ); |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
233 } |
7032 | 234 } |
235 | |
7027 | 236 /* Find our spot in the list */ |
237 p_newtitle = NULL; | |
238 p_title = dvdcss->p_titles; | |
239 while( ( p_title != NULL ) && ( p_title->i_startlb < i_block ) ) | |
240 { | |
241 p_newtitle = p_title; | |
242 p_title = p_title->p_next; | |
243 } | |
244 | |
245 /* Save the found title */ | |
246 p_title = p_newtitle; | |
247 | |
248 /* Write in the new title and its key */ | |
249 p_newtitle = malloc( sizeof( dvd_title_t ) ); | |
250 p_newtitle->i_startlb = i_block; | |
251 memcpy( p_newtitle->p_key, p_title_key, KEY_SIZE ); | |
252 | |
253 /* Link it at the head of the (possibly empty) list */ | |
254 if( p_title == NULL ) | |
255 { | |
256 p_newtitle->p_next = dvdcss->p_titles; | |
257 dvdcss->p_titles = p_newtitle; | |
258 } | |
259 /* Link the new title inside the list */ | |
260 else | |
261 { | |
262 p_newtitle->p_next = p_title->p_next; | |
263 p_title->p_next = p_newtitle; | |
264 } | |
265 | |
266 memcpy( dvdcss->css.p_title_key, p_title_key, KEY_SIZE ); | |
267 return 0; | |
268 } | |
269 | |
270 /***************************************************************************** | |
271 * _dvdcss_disckey: get disc key. | |
272 ***************************************************************************** | |
273 * This function should only be called if DVD ioctls are present. | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
274 * It will set dvdcss->i_method = DVDCSS_METHOD_TITLE if it fails to find |
7027 | 275 * a valid disc key. |
276 * Two decryption methods are offered: | |
277 * -disc key hash crack, | |
278 * -decryption with player keys if they are available. | |
279 *****************************************************************************/ | |
280 int _dvdcss_disckey( dvdcss_t dvdcss ) | |
281 { | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
282 unsigned char p_buffer[ DVD_DISCKEY_SIZE ]; |
7027 | 283 dvd_key_t p_disc_key; |
284 int i; | |
285 | |
286 if( GetBusKey( dvdcss ) < 0 ) | |
287 { | |
288 return -1; | |
289 } | |
290 | |
291 /* Get encrypted disc key */ | |
292 if( ioctl_ReadDiscKey( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 ) | |
293 { | |
16630 | 294 print_error( dvdcss, "ioctl ReadDiscKey failed" ); |
7027 | 295 return -1; |
296 } | |
297 | |
298 /* This should have invaidated the AGID and got us ASF=1. */ | |
299 if( GetASF( dvdcss ) != 1 ) | |
300 { | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
301 /* Region mismatch (or region not set) is the most likely source. */ |
16630 | 302 print_error( dvdcss, |
303 "ASF not 1 after reading disc key (region mismatch?)" ); | |
7027 | 304 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); |
305 return -1; | |
306 } | |
307 | |
16630 | 308 /* Shuffle disc key using bus key */ |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
309 for( i = 0 ; i < DVD_DISCKEY_SIZE ; i++ ) |
7027 | 310 { |
311 p_buffer[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ]; | |
312 } | |
313 | |
16630 | 314 /* Decrypt disc key */ |
7027 | 315 switch( dvdcss->i_method ) |
316 { | |
317 case DVDCSS_METHOD_KEY: | |
318 | |
319 /* Decrypt disc key with player key. */ | |
16630 | 320 PrintKey( dvdcss, "decrypting disc key ", p_buffer ); |
321 if( ! DecryptDiscKey( dvdcss, p_buffer, p_disc_key ) ) | |
7027 | 322 { |
323 PrintKey( dvdcss, "decrypted disc key is ", p_disc_key ); | |
324 break; | |
325 } | |
16630 | 326 print_debug( dvdcss, "failed to decrypt the disc key, " |
327 "faulty drive/kernel? " | |
328 "cracking title keys instead" ); | |
7027 | 329 |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
330 /* Fallback, but not to DISC as the disc key might be faulty */ |
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
331 dvdcss->i_method = DVDCSS_METHOD_TITLE; |
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
332 break; |
7027 | 333 |
334 case DVDCSS_METHOD_DISC: | |
335 | |
336 /* Crack Disc key to be able to use it */ | |
337 memcpy( p_disc_key, p_buffer, KEY_SIZE ); | |
16630 | 338 PrintKey( dvdcss, "cracking disc key ", p_disc_key ); |
7027 | 339 if( ! CrackDiscKey( dvdcss, p_disc_key ) ) |
340 { | |
341 PrintKey( dvdcss, "cracked disc key is ", p_disc_key ); | |
342 break; | |
343 } | |
16630 | 344 print_debug( dvdcss, "failed to crack the disc key" ); |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
345 memset( p_disc_key, 0, KEY_SIZE ); |
7027 | 346 dvdcss->i_method = DVDCSS_METHOD_TITLE; |
347 break; | |
348 | |
349 default: | |
350 | |
16630 | 351 print_debug( dvdcss, "disc key needs not be decrypted" ); |
7027 | 352 memset( p_disc_key, 0, KEY_SIZE ); |
353 break; | |
354 } | |
355 | |
356 memcpy( dvdcss->css.p_disc_key, p_disc_key, KEY_SIZE ); | |
357 | |
358 return 0; | |
359 } | |
360 | |
361 | |
362 /***************************************************************************** | |
363 * _dvdcss_titlekey: get title key. | |
364 *****************************************************************************/ | |
365 int _dvdcss_titlekey( dvdcss_t dvdcss, int i_pos, dvd_key_t p_title_key ) | |
366 { | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
367 static uint8_t p_garbage[ DVDCSS_BLOCK_SIZE ]; /* we never read it back */ |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
368 uint8_t p_key[ KEY_SIZE ]; |
7027 | 369 int i, i_ret = 0; |
370 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
371 if( dvdcss->b_ioctls && ( dvdcss->i_method == DVDCSS_METHOD_KEY || |
7027 | 372 dvdcss->i_method == DVDCSS_METHOD_DISC ) ) |
373 { | |
374 /* We have a decrypted Disc key and the ioctls are available, | |
375 * read the title key and decrypt it. | |
376 */ | |
377 | |
16630 | 378 print_debug( dvdcss, "getting title key at block %i the classic way", |
379 i_pos ); | |
7027 | 380 |
381 /* We need to authenticate again every time to get a new session key */ | |
382 if( GetBusKey( dvdcss ) < 0 ) | |
383 { | |
384 return -1; | |
385 } | |
386 | |
387 /* Get encrypted title key */ | |
388 if( ioctl_ReadTitleKey( dvdcss->i_fd, &dvdcss->css.i_agid, | |
389 i_pos, p_key ) < 0 ) | |
390 { | |
16630 | 391 print_debug( dvdcss, |
392 "ioctl ReadTitleKey failed (region mismatch?)" ); | |
7027 | 393 i_ret = -1; |
394 } | |
395 | |
396 /* Test ASF, it will be reset to 0 if we got a Region error */ | |
397 switch( GetASF( dvdcss ) ) | |
398 { | |
399 case -1: | |
400 /* An error getting the ASF status, something must be wrong. */ | |
16630 | 401 print_debug( dvdcss, "lost ASF requesting title key" ); |
7027 | 402 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); |
403 i_ret = -1; | |
404 break; | |
405 | |
406 case 0: | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
407 /* This might either be a title that has no key, |
7027 | 408 * or we encountered a region error. */ |
16630 | 409 print_debug( dvdcss, "lost ASF requesting title key" ); |
7027 | 410 break; |
411 | |
412 case 1: | |
413 /* Drive status is ok. */ | |
414 /* If the title key request failed, but we did not loose ASF, | |
415 * we might stil have the AGID. Other code assume that we | |
416 * will not after this so invalidate it(?). */ | |
417 if( i_ret < 0 ) | |
418 { | |
419 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); | |
420 } | |
421 break; | |
422 } | |
423 | |
424 if( !( i_ret < 0 ) ) | |
425 { | |
426 /* Decrypt title key using the bus key */ | |
427 for( i = 0 ; i < KEY_SIZE ; i++ ) | |
428 { | |
429 p_key[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ]; | |
430 } | |
431 | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
432 /* If p_key is all zero then there really wasn't any key present |
7027 | 433 * even though we got to read it without an error. */ |
434 if( !( p_key[0] | p_key[1] | p_key[2] | p_key[3] | p_key[4] ) ) | |
435 { | |
436 i_ret = 0; | |
437 } | |
438 else | |
439 { | |
16630 | 440 PrintKey( dvdcss, "initial disc key ", dvdcss->css.p_disc_key ); |
7027 | 441 DecryptTitleKey( dvdcss->css.p_disc_key, p_key ); |
16630 | 442 PrintKey( dvdcss, "decrypted title key ", p_key ); |
7027 | 443 i_ret = 1; |
444 } | |
445 | |
446 /* All went well either there wasn't a key or we have it now. */ | |
447 memcpy( p_title_key, p_key, KEY_SIZE ); | |
448 PrintKey( dvdcss, "title key is ", p_title_key ); | |
449 | |
450 return i_ret; | |
451 } | |
452 | |
453 /* The title key request failed */ | |
16630 | 454 print_debug( dvdcss, "resetting drive and cracking title key" ); |
7027 | 455 |
456 /* Read an unscrambled sector and reset the drive */ | |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
457 dvdcss->pf_seek( dvdcss, 0 ); |
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
458 dvdcss->pf_read( dvdcss, p_garbage, 1 ); |
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
459 dvdcss->pf_seek( dvdcss, 0 ); |
7027 | 460 _dvdcss_disckey( dvdcss ); |
461 | |
462 /* Fallback */ | |
463 } | |
464 | |
465 /* METHOD is TITLE, we can't use the ioctls or requesting the title key | |
466 * failed above. For these cases we try to crack the key instead. */ | |
467 | |
468 /* For now, the read limit is 9Gb / 2048 = 4718592 sectors. */ | |
469 i_ret = CrackTitleKey( dvdcss, i_pos, 4718592, p_key ); | |
470 | |
471 memcpy( p_title_key, p_key, KEY_SIZE ); | |
472 PrintKey( dvdcss, "title key is ", p_title_key ); | |
473 | |
474 return i_ret; | |
475 } | |
476 | |
477 /***************************************************************************** | |
478 * _dvdcss_unscramble: does the actual descrambling of data | |
479 ***************************************************************************** | |
480 * sec : sector to unscramble | |
481 * key : title key for this sector | |
482 *****************************************************************************/ | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
483 int _dvdcss_unscramble( dvd_key_t p_key, uint8_t *p_sec ) |
7027 | 484 { |
485 unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6; | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
486 uint8_t *p_end = p_sec + DVDCSS_BLOCK_SIZE; |
7027 | 487 |
488 /* PES_scrambling_control */ | |
16630 | 489 if( !(p_sec[0x14] & 0x30) ) |
7027 | 490 { |
16630 | 491 return 0; |
492 } | |
493 | |
494 i_t1 = (p_key[0] ^ p_sec[0x54]) | 0x100; | |
495 i_t2 = p_key[1] ^ p_sec[0x55]; | |
496 i_t3 = (p_key[2] | (p_key[3] << 8) | | |
497 (p_key[4] << 16)) ^ (p_sec[0x56] | | |
498 (p_sec[0x57] << 8) | (p_sec[0x58] << 16)); | |
499 i_t4 = i_t3 & 7; | |
500 i_t3 = i_t3 * 2 + 8 - i_t4; | |
501 p_sec += 0x80; | |
502 i_t5 = 0; | |
7027 | 503 |
16630 | 504 while( p_sec != p_end ) |
505 { | |
506 i_t4 = p_css_tab2[i_t2] ^ p_css_tab3[i_t1]; | |
507 i_t2 = i_t1>>1; | |
508 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4; | |
509 i_t4 = p_css_tab5[i_t4]; | |
510 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^ | |
511 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff; | |
512 i_t3 = (i_t3 << 8 ) | i_t6; | |
513 i_t6 = p_css_tab4[i_t6]; | |
514 i_t5 += i_t6 + i_t4; | |
515 *p_sec = p_css_tab1[*p_sec] ^ ( i_t5 & 0xff ); | |
516 p_sec++; | |
517 i_t5 >>= 8; | |
7027 | 518 } |
519 | |
520 return 0; | |
521 } | |
522 | |
523 /* Following functions are local */ | |
524 | |
525 /***************************************************************************** | |
16630 | 526 * GetBusKey : Go through the CSS Authentication process |
527 ***************************************************************************** | |
528 * It simulates the mutual authentication between logical unit and host, | |
529 * and stops when a session key (called bus key) has been established. | |
530 * Always do the full auth sequence. Some drives seem to lie and always | |
531 * respond with ASF=1. For instance the old DVD roms on Compaq Armada says | |
532 * that ASF=1 from the start and then later fail with a 'read of scrambled | |
533 * block without authentication' error. | |
534 *****************************************************************************/ | |
535 static int GetBusKey( dvdcss_t dvdcss ) | |
536 { | |
537 uint8_t p_buffer[10]; | |
538 uint8_t p_challenge[2*KEY_SIZE]; | |
539 dvd_key_t p_key1; | |
540 dvd_key_t p_key2; | |
541 dvd_key_t p_key_check; | |
542 uint8_t i_variant = 0; | |
543 int i_ret = -1; | |
544 int i; | |
545 | |
546 print_debug( dvdcss, "requesting AGID" ); | |
547 i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); | |
548 | |
549 /* We might have to reset hung authentication processes in the drive | |
550 * by invalidating the corresponding AGID'. As long as we haven't got | |
551 * an AGID, invalidate one (in sequence) and try again. */ | |
552 for( i = 0; i_ret == -1 && i < 4 ; ++i ) | |
553 { | |
554 print_debug( dvdcss, "ioctl ReportAgid failed, " | |
555 "invalidating AGID %d", i ); | |
556 | |
557 /* This is really _not good_, should be handled by the OS. | |
558 * Invalidating an AGID could make another process fail somewhere | |
559 * in its authentication process. */ | |
560 dvdcss->css.i_agid = i; | |
561 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); | |
562 | |
563 print_debug( dvdcss, "requesting AGID" ); | |
564 i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); | |
565 } | |
566 | |
567 /* Unable to authenticate without AGID */ | |
568 if( i_ret == -1 ) | |
569 { | |
570 print_error( dvdcss, "ioctl ReportAgid failed, fatal" ); | |
571 return -1; | |
572 } | |
573 | |
574 /* Setup a challenge, any values should work */ | |
575 for( i = 0 ; i < 10; ++i ) | |
576 { | |
577 p_challenge[i] = i; | |
578 } | |
579 | |
580 /* Get challenge from host */ | |
581 for( i = 0 ; i < 10 ; ++i ) | |
582 { | |
583 p_buffer[9-i] = p_challenge[i]; | |
584 } | |
585 | |
586 /* Send challenge to LU */ | |
587 if( ioctl_SendChallenge( dvdcss->i_fd, | |
588 &dvdcss->css.i_agid, p_buffer ) < 0 ) | |
589 { | |
590 print_error( dvdcss, "ioctl SendChallenge failed" ); | |
591 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); | |
592 return -1; | |
593 } | |
594 | |
595 /* Get key1 from LU */ | |
596 if( ioctl_ReportKey1( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0) | |
597 { | |
598 print_error( dvdcss, "ioctl ReportKey1 failed" ); | |
599 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); | |
600 return -1; | |
601 } | |
602 | |
603 /* Send key1 to host */ | |
604 for( i = 0 ; i < KEY_SIZE ; i++ ) | |
605 { | |
606 p_key1[i] = p_buffer[4-i]; | |
607 } | |
608 | |
609 for( i = 0 ; i < 32 ; ++i ) | |
610 { | |
611 CryptKey( 0, i, p_challenge, p_key_check ); | |
612 | |
613 if( memcmp( p_key_check, p_key1, KEY_SIZE ) == 0 ) | |
614 { | |
615 print_debug( dvdcss, "drive authenticated, using variant %d", i ); | |
616 i_variant = i; | |
617 break; | |
618 } | |
619 } | |
620 | |
621 if( i == 32 ) | |
622 { | |
623 print_error( dvdcss, "drive would not authenticate" ); | |
624 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); | |
625 return -1; | |
626 } | |
627 | |
628 /* Get challenge from LU */ | |
629 if( ioctl_ReportChallenge( dvdcss->i_fd, | |
630 &dvdcss->css.i_agid, p_buffer ) < 0 ) | |
631 { | |
632 print_error( dvdcss, "ioctl ReportKeyChallenge failed" ); | |
633 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); | |
634 return -1; | |
635 } | |
636 | |
637 /* Send challenge to host */ | |
638 for( i = 0 ; i < 10 ; ++i ) | |
639 { | |
640 p_challenge[i] = p_buffer[9-i]; | |
641 } | |
642 | |
643 CryptKey( 1, i_variant, p_challenge, p_key2 ); | |
644 | |
645 /* Get key2 from host */ | |
646 for( i = 0 ; i < KEY_SIZE ; ++i ) | |
647 { | |
648 p_buffer[4-i] = p_key2[i]; | |
649 } | |
650 | |
651 /* Send key2 to LU */ | |
652 if( ioctl_SendKey2( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 ) | |
653 { | |
654 print_error( dvdcss, "ioctl SendKey2 failed" ); | |
655 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); | |
656 return -1; | |
657 } | |
658 | |
659 /* The drive has accepted us as authentic. */ | |
660 print_debug( dvdcss, "authentication established" ); | |
661 | |
662 memcpy( p_challenge, p_key1, KEY_SIZE ); | |
663 memcpy( p_challenge + KEY_SIZE, p_key2, KEY_SIZE ); | |
664 | |
665 CryptKey( 2, i_variant, p_challenge, dvdcss->css.p_bus_key ); | |
666 | |
667 return 0; | |
668 } | |
669 | |
670 /***************************************************************************** | |
671 * PrintKey : debug function that dumps a key value | |
672 *****************************************************************************/ | |
673 static void PrintKey( dvdcss_t dvdcss, char *prefix, uint8_t const *data ) | |
674 { | |
675 print_debug( dvdcss, "%s%02x:%02x:%02x:%02x:%02x", prefix, | |
676 data[0], data[1], data[2], data[3], data[4] ); | |
677 } | |
678 | |
679 /***************************************************************************** | |
7027 | 680 * GetASF : Get Authentication success flag |
681 ***************************************************************************** | |
682 * Returns : | |
683 * -1 on ioctl error, | |
684 * 0 if the device needs to be authenticated, | |
685 * 1 either. | |
686 *****************************************************************************/ | |
687 static int GetASF( dvdcss_t dvdcss ) | |
688 { | |
689 int i_asf = 0; | |
690 | |
691 if( ioctl_ReportASF( dvdcss->i_fd, NULL, &i_asf ) != 0 ) | |
692 { | |
693 /* The ioctl process has failed */ | |
16630 | 694 print_error( dvdcss, "GetASF fatal error" ); |
7027 | 695 return -1; |
696 } | |
697 | |
698 if( i_asf ) | |
699 { | |
16630 | 700 print_debug( dvdcss, "GetASF authenticated, ASF=1" ); |
7027 | 701 } |
702 else | |
703 { | |
16630 | 704 print_debug( dvdcss, "GetASF not authenticated, ASF=0" ); |
7027 | 705 } |
706 | |
707 return i_asf; | |
708 } | |
709 | |
710 /***************************************************************************** | |
711 * CryptKey : shuffles bits and unencrypt keys. | |
712 ***************************************************************************** | |
713 * Used during authentication and disc key negociation in GetBusKey. | |
714 * i_key_type : 0->key1, 1->key2, 2->buskey. | |
715 * i_variant : between 0 and 31. | |
716 *****************************************************************************/ | |
717 static void CryptKey( int i_key_type, int i_variant, | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
718 uint8_t const *p_challenge, uint8_t *p_key ) |
7027 | 719 { |
720 /* Permutation table for challenge */ | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
721 uint8_t pp_perm_challenge[3][10] = |
7027 | 722 { { 1, 3, 0, 7, 5, 2, 9, 6, 4, 8 }, |
723 { 6, 1, 9, 3, 8, 5, 7, 4, 0, 2 }, | |
724 { 4, 0, 3, 5, 7, 2, 8, 6, 1, 9 } }; | |
725 | |
726 /* Permutation table for variant table for key2 and buskey */ | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
727 uint8_t pp_perm_variant[2][32] = |
7027 | 728 { { 0x0a, 0x08, 0x0e, 0x0c, 0x0b, 0x09, 0x0f, 0x0d, |
729 0x1a, 0x18, 0x1e, 0x1c, 0x1b, 0x19, 0x1f, 0x1d, | |
730 0x02, 0x00, 0x06, 0x04, 0x03, 0x01, 0x07, 0x05, | |
731 0x12, 0x10, 0x16, 0x14, 0x13, 0x11, 0x17, 0x15 }, | |
732 { 0x12, 0x1a, 0x16, 0x1e, 0x02, 0x0a, 0x06, 0x0e, | |
733 0x10, 0x18, 0x14, 0x1c, 0x00, 0x08, 0x04, 0x0c, | |
734 0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f, | |
735 0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d } }; | |
736 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
737 uint8_t p_variants[32] = |
7027 | 738 { 0xB7, 0x74, 0x85, 0xD0, 0xCC, 0xDB, 0xCA, 0x73, |
739 0x03, 0xFE, 0x31, 0x03, 0x52, 0xE0, 0xB7, 0x42, | |
740 0x63, 0x16, 0xF2, 0x2A, 0x79, 0x52, 0xFF, 0x1B, | |
741 0x7A, 0x11, 0xCA, 0x1A, 0x9B, 0x40, 0xAD, 0x01 }; | |
742 | |
743 /* The "secret" key */ | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
744 uint8_t p_secret[5] = { 0x55, 0xD6, 0xC4, 0xC5, 0x28 }; |
7027 | 745 |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
746 uint8_t p_bits[30], p_scratch[10], p_tmp1[5], p_tmp2[5]; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
747 uint8_t i_lfsr0_o; /* 1 bit used */ |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
748 uint8_t i_lfsr1_o; /* 1 bit used */ |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
749 uint8_t i_css_variant, i_cse, i_index, i_combined, i_carry; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
750 uint8_t i_val = 0; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
751 uint32_t i_lfsr0, i_lfsr1; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
752 int i_term = 0; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
753 int i_bit; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
754 int i; |
7027 | 755 |
756 for (i = 9; i >= 0; --i) | |
757 p_scratch[i] = p_challenge[pp_perm_challenge[i_key_type][i]]; | |
758 | |
759 i_css_variant = ( i_key_type == 0 ) ? i_variant : | |
760 pp_perm_variant[i_key_type-1][i_variant]; | |
761 | |
762 /* | |
763 * This encryption engine implements one of 32 variations | |
764 * one the same theme depending upon the choice in the | |
765 * variant parameter (0 - 31). | |
766 * | |
767 * The algorithm itself manipulates a 40 bit input into | |
768 * a 40 bit output. | |
769 * The parameter 'input' is 80 bits. It consists of | |
770 * the 40 bit input value that is to be encrypted followed | |
771 * by a 40 bit seed value for the pseudo random number | |
772 * generators. | |
773 */ | |
774 | |
775 /* Feed the secret into the input values such that | |
776 * we alter the seed to the LFSR's used above, then | |
777 * generate the bits to play with. | |
778 */ | |
779 for( i = 5 ; --i >= 0 ; ) | |
780 { | |
781 p_tmp1[i] = p_scratch[5 + i] ^ p_secret[i] ^ p_crypt_tab2[i]; | |
782 } | |
783 | |
784 /* | |
785 * We use two LFSR's (seeded from some of the input data bytes) to | |
786 * generate two streams of pseudo-random bits. These two bit streams | |
787 * are then combined by simply adding with carry to generate a final | |
788 * sequence of pseudo-random bits which is stored in the buffer that | |
789 * 'output' points to the end of - len is the size of this buffer. | |
790 * | |
791 * The first LFSR is of degree 25, and has a polynomial of: | |
792 * x^13 + x^5 + x^4 + x^1 + 1 | |
793 * | |
794 * The second LSFR is of degree 17, and has a (primitive) polynomial of: | |
795 * x^15 + x^1 + 1 | |
796 * | |
797 * I don't know if these polynomials are primitive modulo 2, and thus | |
798 * represent maximal-period LFSR's. | |
799 * | |
800 * | |
801 * Note that we take the output of each LFSR from the new shifted in | |
802 * bit, not the old shifted out bit. Thus for ease of use the LFSR's | |
803 * are implemented in bit reversed order. | |
804 * | |
805 */ | |
806 | |
807 /* In order to ensure that the LFSR works we need to ensure that the | |
808 * initial values are non-zero. Thus when we initialise them from | |
809 * the seed, we ensure that a bit is set. | |
810 */ | |
811 i_lfsr0 = ( p_tmp1[0] << 17 ) | ( p_tmp1[1] << 9 ) | | |
812 (( p_tmp1[2] & ~7 ) << 1 ) | 8 | ( p_tmp1[2] & 7 ); | |
813 i_lfsr1 = ( p_tmp1[3] << 9 ) | 0x100 | p_tmp1[4]; | |
814 | |
815 i_index = sizeof(p_bits); | |
816 i_carry = 0; | |
817 | |
818 do | |
819 { | |
820 for( i_bit = 0, i_val = 0 ; i_bit < 8 ; ++i_bit ) | |
821 { | |
822 | |
823 i_lfsr0_o = ( ( i_lfsr0 >> 24 ) ^ ( i_lfsr0 >> 21 ) ^ | |
824 ( i_lfsr0 >> 20 ) ^ ( i_lfsr0 >> 12 ) ) & 1; | |
825 i_lfsr0 = ( i_lfsr0 << 1 ) | i_lfsr0_o; | |
826 | |
827 i_lfsr1_o = ( ( i_lfsr1 >> 16 ) ^ ( i_lfsr1 >> 2 ) ) & 1; | |
828 i_lfsr1 = ( i_lfsr1 << 1 ) | i_lfsr1_o; | |
829 | |
830 i_combined = !i_lfsr1_o + i_carry + !i_lfsr0_o; | |
831 /* taking bit 1 */ | |
832 i_carry = ( i_combined >> 1 ) & 1; | |
833 i_val |= ( i_combined & 1 ) << i_bit; | |
834 } | |
835 | |
836 p_bits[--i_index] = i_val; | |
837 } while( i_index > 0 ); | |
838 | |
839 /* This term is used throughout the following to | |
840 * select one of 32 different variations on the | |
841 * algorithm. | |
842 */ | |
843 i_cse = p_variants[i_css_variant] ^ p_crypt_tab2[i_css_variant]; | |
844 | |
845 /* Now the actual blocks doing the encryption. Each | |
846 * of these works on 40 bits at a time and are quite | |
847 * similar. | |
848 */ | |
849 i_index = 0; | |
850 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_scratch[i] ) | |
851 { | |
852 i_index = p_bits[25 + i] ^ p_scratch[i]; | |
853 i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse; | |
854 | |
855 p_tmp1[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term; | |
856 } | |
857 p_tmp1[4] ^= p_tmp1[0]; | |
858 | |
859 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp1[i] ) | |
860 { | |
861 i_index = p_bits[20 + i] ^ p_tmp1[i]; | |
862 i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse; | |
863 | |
864 p_tmp2[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term; | |
865 } | |
866 p_tmp2[4] ^= p_tmp2[0]; | |
867 | |
868 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp2[i] ) | |
869 { | |
870 i_index = p_bits[15 + i] ^ p_tmp2[i]; | |
871 i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse; | |
872 i_index = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term; | |
873 | |
874 p_tmp1[i] = p_crypt_tab0[i_index] ^ p_crypt_tab2[i_index]; | |
875 } | |
876 p_tmp1[4] ^= p_tmp1[0]; | |
877 | |
878 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp1[i] ) | |
879 { | |
880 i_index = p_bits[10 + i] ^ p_tmp1[i]; | |
881 i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse; | |
882 | |
883 i_index = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term; | |
884 | |
885 p_tmp2[i] = p_crypt_tab0[i_index] ^ p_crypt_tab2[i_index]; | |
886 } | |
887 p_tmp2[4] ^= p_tmp2[0]; | |
888 | |
889 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp2[i] ) | |
890 { | |
891 i_index = p_bits[5 + i] ^ p_tmp2[i]; | |
892 i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse; | |
893 | |
894 p_tmp1[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term; | |
895 } | |
896 p_tmp1[4] ^= p_tmp1[0]; | |
897 | |
898 for(i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp1[i] ) | |
899 { | |
900 i_index = p_bits[i] ^ p_tmp1[i]; | |
901 i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse; | |
902 | |
903 p_key[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term; | |
904 } | |
905 | |
906 return; | |
907 } | |
908 | |
909 /***************************************************************************** | |
910 * DecryptKey: decrypt p_crypted with p_key. | |
911 ***************************************************************************** | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
912 * Used to decrypt the disc key, with a player key, after requesting it |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
913 * in _dvdcss_disckey and to decrypt title keys, with a disc key, requested |
7027 | 914 * in _dvdcss_titlekey. |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
915 * The player keys and the resulting disc key are only used as KEKs |
7027 | 916 * (key encryption keys). |
917 * Decryption is slightly dependant on the type of key: | |
918 * -for disc key, invert is 0x00, | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
919 * -for title key, invert if 0xff. |
7027 | 920 *****************************************************************************/ |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
921 static void DecryptKey( uint8_t invert, uint8_t const *p_key, |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
922 uint8_t const *p_crypted, uint8_t *p_result ) |
7027 | 923 { |
924 unsigned int i_lfsr1_lo; | |
925 unsigned int i_lfsr1_hi; | |
926 unsigned int i_lfsr0; | |
927 unsigned int i_combined; | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
928 uint8_t o_lfsr0; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
929 uint8_t o_lfsr1; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
930 uint8_t k[5]; |
7027 | 931 int i; |
932 | |
933 i_lfsr1_lo = p_key[0] | 0x100; | |
934 i_lfsr1_hi = p_key[1]; | |
935 | |
936 i_lfsr0 = ( ( p_key[4] << 17 ) | |
937 | ( p_key[3] << 9 ) | |
938 | ( p_key[2] << 1 ) ) | |
939 + 8 - ( p_key[2] & 7 ); | |
940 i_lfsr0 = ( p_css_tab4[i_lfsr0 & 0xff] << 24 ) | | |
941 ( p_css_tab4[( i_lfsr0 >> 8 ) & 0xff] << 16 ) | | |
942 ( p_css_tab4[( i_lfsr0 >> 16 ) & 0xff] << 8 ) | | |
943 p_css_tab4[( i_lfsr0 >> 24 ) & 0xff]; | |
944 | |
945 i_combined = 0; | |
946 for( i = 0 ; i < KEY_SIZE ; ++i ) | |
947 { | |
948 o_lfsr1 = p_css_tab2[i_lfsr1_hi] ^ p_css_tab3[i_lfsr1_lo]; | |
949 i_lfsr1_hi = i_lfsr1_lo >> 1; | |
950 i_lfsr1_lo = ( ( i_lfsr1_lo & 1 ) << 8 ) ^ o_lfsr1; | |
951 o_lfsr1 = p_css_tab4[o_lfsr1]; | |
952 | |
953 o_lfsr0 = ((((((( i_lfsr0 >> 8 ) ^ i_lfsr0 ) >> 1 ) | |
954 ^ i_lfsr0 ) >> 3 ) ^ i_lfsr0 ) >> 7 ); | |
955 i_lfsr0 = ( i_lfsr0 >> 8 ) | ( o_lfsr0 << 24 ); | |
956 | |
957 i_combined += ( o_lfsr0 ^ invert ) + o_lfsr1; | |
958 k[i] = i_combined & 0xff; | |
959 i_combined >>= 8; | |
960 } | |
961 | |
962 p_result[4] = k[4] ^ p_css_tab1[p_crypted[4]] ^ p_crypted[3]; | |
963 p_result[3] = k[3] ^ p_css_tab1[p_crypted[3]] ^ p_crypted[2]; | |
964 p_result[2] = k[2] ^ p_css_tab1[p_crypted[2]] ^ p_crypted[1]; | |
965 p_result[1] = k[1] ^ p_css_tab1[p_crypted[1]] ^ p_crypted[0]; | |
966 p_result[0] = k[0] ^ p_css_tab1[p_crypted[0]] ^ p_result[4]; | |
967 | |
968 p_result[4] = k[4] ^ p_css_tab1[p_result[4]] ^ p_result[3]; | |
969 p_result[3] = k[3] ^ p_css_tab1[p_result[3]] ^ p_result[2]; | |
970 p_result[2] = k[2] ^ p_css_tab1[p_result[2]] ^ p_result[1]; | |
971 p_result[1] = k[1] ^ p_css_tab1[p_result[1]] ^ p_result[0]; | |
972 p_result[0] = k[0] ^ p_css_tab1[p_result[0]]; | |
973 | |
974 return; | |
975 } | |
976 | |
977 /***************************************************************************** | |
16630 | 978 * player_keys: alternate DVD player keys |
979 ***************************************************************************** | |
980 * These player keys were generated using Frank A. Stevenson's PlayerKey | |
981 * cracker. A copy of his article can be found here: | |
982 * http://www-2.cs.cmu.edu/~dst/DeCSS/FrankStevenson/mail2.txt | |
983 *****************************************************************************/ | |
984 static const dvd_key_t player_keys[] = | |
985 { | |
986 { 0x01, 0xaf, 0xe3, 0x12, 0x80 }, | |
987 { 0x12, 0x11, 0xca, 0x04, 0x3b }, | |
988 { 0x14, 0x0c, 0x9e, 0xd0, 0x09 }, | |
989 { 0x14, 0x71, 0x35, 0xba, 0xe2 }, | |
990 { 0x1a, 0xa4, 0x33, 0x21, 0xa6 }, | |
991 { 0x26, 0xec, 0xc4, 0xa7, 0x4e }, | |
992 { 0x2c, 0xb2, 0xc1, 0x09, 0xee }, | |
993 { 0x2f, 0x25, 0x9e, 0x96, 0xdd }, | |
994 { 0x33, 0x2f, 0x49, 0x6c, 0xe0 }, | |
995 { 0x35, 0x5b, 0xc1, 0x31, 0x0f }, | |
996 { 0x36, 0x67, 0xb2, 0xe3, 0x85 }, | |
997 { 0x39, 0x3d, 0xf1, 0xf1, 0xbd }, | |
998 { 0x3b, 0x31, 0x34, 0x0d, 0x91 }, | |
999 { 0x45, 0xed, 0x28, 0xeb, 0xd3 }, | |
1000 { 0x48, 0xb7, 0x6c, 0xce, 0x69 }, | |
1001 { 0x4b, 0x65, 0x0d, 0xc1, 0xee }, | |
1002 { 0x4c, 0xbb, 0xf5, 0x5b, 0x23 }, | |
1003 { 0x51, 0x67, 0x67, 0xc5, 0xe0 }, | |
1004 { 0x53, 0x94, 0xe1, 0x75, 0xbf }, | |
1005 { 0x57, 0x2c, 0x8b, 0x31, 0xae }, | |
1006 { 0x63, 0xdb, 0x4c, 0x5b, 0x4a }, | |
1007 { 0x7b, 0x1e, 0x5e, 0x2b, 0x57 }, | |
1008 { 0x85, 0xf3, 0x85, 0xa0, 0xe0 }, | |
1009 { 0xab, 0x1e, 0xe7, 0x7b, 0x72 }, | |
1010 { 0xab, 0x36, 0xe3, 0xeb, 0x76 }, | |
1011 { 0xb1, 0xb8, 0xf9, 0x38, 0x03 }, | |
1012 { 0xb8, 0x5d, 0xd8, 0x53, 0xbd }, | |
1013 { 0xbf, 0x92, 0xc3, 0xb0, 0xe2 }, | |
1014 { 0xcf, 0x1a, 0xb2, 0xf8, 0x0a }, | |
1015 { 0xec, 0xa0, 0xcf, 0xb3, 0xff }, | |
1016 { 0xfc, 0x95, 0xa9, 0x87, 0x35 } | |
1017 }; | |
1018 | |
1019 /***************************************************************************** | |
7027 | 1020 * DecryptDiscKey |
1021 ***************************************************************************** | |
16630 | 1022 * Decryption of the disc key with player keys: try to decrypt the disc key |
1023 * from every position with every player key. | |
7027 | 1024 * p_struct_disckey: the 2048 byte DVD_STRUCT_DISCKEY data |
1025 * p_disc_key: result, the 5 byte disc key | |
1026 *****************************************************************************/ | |
16630 | 1027 static int DecryptDiscKey( dvdcss_t dvdcss, uint8_t const *p_struct_disckey, |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1028 dvd_key_t p_disc_key ) |
7027 | 1029 { |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1030 uint8_t p_verify[KEY_SIZE]; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1031 unsigned int i, n = 0; |
7027 | 1032 |
16630 | 1033 /* Decrypt disc key with the above player keys */ |
1034 for( n = 0; n < sizeof(player_keys) / sizeof(dvd_key_t); n++ ) | |
7027 | 1035 { |
16630 | 1036 PrintKey( dvdcss, "trying player key ", player_keys[n] ); |
7027 | 1037 |
1038 for( i = 1; i < 409; i++ ) | |
1039 { | |
1040 /* Check if player key n is the right key for position i. */ | |
1041 DecryptKey( 0, player_keys[n], p_struct_disckey + 5 * i, | |
1042 p_disc_key ); | |
1043 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1044 /* The first part in the struct_disckey block is the |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1045 * 'disc key' encrypted with itself. Using this we |
7027 | 1046 * can check if we decrypted the correct key. */ |
1047 DecryptKey( 0, p_disc_key, p_struct_disckey, p_verify ); | |
1048 | |
1049 /* If the position / player key pair worked then return. */ | |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
1050 if( memcmp( p_disc_key, p_verify, KEY_SIZE ) == 0 ) |
7027 | 1051 { |
1052 return 0; | |
1053 } | |
1054 } | |
1055 } | |
1056 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1057 /* Have tried all combinations of positions and keys, |
7027 | 1058 * and we still didn't succeed. */ |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
1059 memset( p_disc_key, 0, KEY_SIZE ); |
7027 | 1060 return -1; |
1061 } | |
1062 | |
1063 /***************************************************************************** | |
1064 * DecryptTitleKey | |
1065 ***************************************************************************** | |
1066 * Decrypt the title key using the disc key. | |
1067 * p_disc_key: result, the 5 byte disc key | |
1068 * p_titlekey: the encrypted title key, gets overwritten by the decrypted key | |
1069 *****************************************************************************/ | |
1070 static void DecryptTitleKey( dvd_key_t p_disc_key, dvd_key_t p_titlekey ) | |
1071 { | |
1072 DecryptKey( 0xff, p_disc_key, p_titlekey, p_titlekey ); | |
1073 } | |
1074 | |
1075 /***************************************************************************** | |
1076 * CrackDiscKey: brute force disc key | |
1077 * CSS hash reversal function designed by Frank Stevenson | |
1078 ***************************************************************************** | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1079 * This function uses a big amount of memory to crack the disc key from the |
7027 | 1080 * disc key hash, if player keys are not available. |
1081 *****************************************************************************/ | |
1082 #define K1TABLEWIDTH 10 | |
1083 | |
1084 /* | |
1085 * Simple function to test if a candidate key produces the given hash | |
1086 */ | |
1087 static int investigate( unsigned char *hash, unsigned char *ckey ) | |
1088 { | |
1089 unsigned char key[KEY_SIZE]; | |
1090 | |
1091 DecryptKey( 0, ckey, hash, key ); | |
1092 | |
1093 return memcmp( key, ckey, KEY_SIZE ); | |
1094 } | |
1095 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1096 static int CrackDiscKey( dvdcss_t dvdcss, uint8_t *p_disc_key ) |
7027 | 1097 { |
1098 unsigned char B[5] = { 0,0,0,0,0 }; /* Second Stage of mangle cipher */ | |
1099 unsigned char C[5] = { 0,0,0,0,0 }; /* Output Stage of mangle cipher | |
1100 * IntermediateKey */ | |
1101 unsigned char k[5] = { 0,0,0,0,0 }; /* Mangling cipher key | |
1102 * Also output from CSS( C ) */ | |
1103 unsigned char out1[5]; /* five first output bytes of LFSR1 */ | |
1104 unsigned char out2[5]; /* five first output bytes of LFSR2 */ | |
1105 unsigned int lfsr1a; /* upper 9 bits of LFSR1 */ | |
1106 unsigned int lfsr1b; /* lower 8 bits of LFSR1 */ | |
1107 unsigned int tmp, tmp2, tmp3, tmp4,tmp5; | |
1108 int i,j; | |
1109 unsigned int nStepA; /* iterator for LFSR1 start state */ | |
1110 unsigned int nStepB; /* iterator for possible B[0] */ | |
1111 unsigned int nTry; /* iterator for K[1] possibilities */ | |
1112 unsigned int nPossibleK1; /* #of possible K[1] values */ | |
1113 unsigned char* K1table; /* Lookup table for possible K[1] */ | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1114 unsigned int* BigTable; /* LFSR2 startstate indexed by |
7027 | 1115 * 1,2,5 output byte */ |
1116 | |
1117 /* | |
1118 * Prepare tables for hash reversal | |
1119 */ | |
1120 | |
1121 /* initialize lookup tables for k[1] */ | |
1122 K1table = malloc( 65536 * K1TABLEWIDTH ); | |
1123 memset( K1table, 0 , 65536 * K1TABLEWIDTH ); | |
1124 if( K1table == NULL ) | |
1125 { | |
1126 return -1; | |
1127 } | |
1128 | |
1129 tmp = p_disc_key[0] ^ p_css_tab1[ p_disc_key[1] ]; | |
1130 for( i = 0 ; i < 256 ; i++ ) /* k[1] */ | |
1131 { | |
1132 tmp2 = p_css_tab1[ tmp ^ i ]; /* p_css_tab1[ B[1] ]*/ | |
1133 | |
1134 for( j = 0 ; j < 256 ; j++ ) /* B[0] */ | |
1135 { | |
1136 tmp3 = j ^ tmp2 ^ i; /* C[1] */ | |
1137 tmp4 = K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) ]; /* count of entries here */ | |
1138 tmp4++; | |
1139 /* | |
1140 if( tmp4 == K1TABLEWIDTH ) | |
1141 { | |
16630 | 1142 print_debug( dvdcss, "Table disaster %d", tmp4 ); |
7027 | 1143 } |
1144 */ | |
1145 if( tmp4 < K1TABLEWIDTH ) | |
1146 { | |
1147 K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) + tmp4 ] = i; | |
1148 } | |
1149 K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) ] = tmp4; | |
1150 } | |
1151 } | |
1152 | |
1153 /* Initing our Really big table */ | |
1154 BigTable = malloc( 16777216 * sizeof(int) ); | |
1155 memset( BigTable, 0 , 16777216 * sizeof(int) ); | |
1156 if( BigTable == NULL ) | |
1157 { | |
1158 return -1; | |
1159 } | |
1160 | |
1161 tmp3 = 0; | |
1162 | |
16630 | 1163 print_debug( dvdcss, "initializing the big table" ); |
7027 | 1164 |
1165 for( i = 0 ; i < 16777216 ; i++ ) | |
1166 { | |
1167 tmp = (( i + i ) & 0x1fffff0 ) | 0x8 | ( i & 0x7 ); | |
1168 | |
1169 for( j = 0 ; j < 5 ; j++ ) | |
1170 { | |
1171 tmp2=((((((( tmp >> 3 ) ^ tmp ) >> 1 ) ^ tmp ) >> 8 ) | |
1172 ^ tmp ) >> 5 ) & 0xff; | |
1173 tmp = ( tmp << 8) | tmp2; | |
1174 out2[j] = p_css_tab4[ tmp2 ]; | |
1175 } | |
1176 | |
1177 j = ( out2[0] << 16 ) | ( out2[1] << 8 ) | out2[4]; | |
1178 BigTable[j] = i; | |
1179 } | |
1180 | |
1181 /* | |
1182 * We are done initing, now reverse hash | |
1183 */ | |
1184 tmp5 = p_disc_key[0] ^ p_css_tab1[ p_disc_key[1] ]; | |
1185 | |
1186 for( nStepA = 0 ; nStepA < 65536 ; nStepA ++ ) | |
1187 { | |
1188 lfsr1a = 0x100 | ( nStepA >> 8 ); | |
1189 lfsr1b = nStepA & 0xff; | |
1190 | |
1191 /* Generate 5 first output bytes from lfsr1 */ | |
1192 for( i = 0 ; i < 5 ; i++ ) | |
1193 { | |
1194 tmp = p_css_tab2[ lfsr1b ] ^ p_css_tab3[ lfsr1a ]; | |
1195 lfsr1b = lfsr1a >> 1; | |
1196 lfsr1a = ((lfsr1a&1)<<8) ^ tmp; | |
1197 out1[ i ] = p_css_tab4[ tmp ]; | |
1198 } | |
1199 | |
1200 /* cumpute and cache some variables */ | |
1201 C[0] = nStepA >> 8; | |
1202 C[1] = nStepA & 0xff; | |
1203 tmp = p_disc_key[3] ^ p_css_tab1[ p_disc_key[4] ]; | |
1204 tmp2 = p_css_tab1[ p_disc_key[0] ]; | |
1205 | |
1206 /* Search through all possible B[0] */ | |
1207 for( nStepB = 0 ; nStepB < 256 ; nStepB++ ) | |
1208 { | |
1209 /* reverse parts of the mangling cipher */ | |
1210 B[0] = nStepB; | |
1211 k[0] = p_css_tab1[ B[0] ] ^ C[0]; | |
1212 B[4] = B[0] ^ k[0] ^ tmp2; | |
1213 k[4] = B[4] ^ tmp; | |
1214 nPossibleK1 = K1table[ K1TABLEWIDTH * (256 * B[0] + C[1]) ]; | |
1215 | |
1216 /* Try out all possible values for k[1] */ | |
1217 for( nTry = 0 ; nTry < nPossibleK1 ; nTry++ ) | |
1218 { | |
1219 k[1] = K1table[ K1TABLEWIDTH * (256 * B[0] + C[1]) + nTry + 1 ]; | |
1220 B[1] = tmp5 ^ k[1]; | |
1221 | |
1222 /* reconstruct output from LFSR2 */ | |
1223 tmp3 = ( 0x100 + k[0] - out1[0] ); | |
1224 out2[0] = tmp3 & 0xff; | |
1225 tmp3 = tmp3 & 0x100 ? 0x100 : 0xff; | |
1226 tmp3 = ( tmp3 + k[1] - out1[1] ); | |
1227 out2[1] = tmp3 & 0xff; | |
1228 tmp3 = ( 0x100 + k[4] - out1[4] ); | |
1229 out2[4] = tmp3 & 0xff; /* Can be 1 off */ | |
1230 | |
1231 /* test first possible out2[4] */ | |
1232 tmp4 = ( out2[0] << 16 ) | ( out2[1] << 8 ) | out2[4]; | |
1233 tmp4 = BigTable[ tmp4 ]; | |
1234 C[2] = tmp4 & 0xff; | |
1235 C[3] = ( tmp4 >> 8 ) & 0xff; | |
1236 C[4] = ( tmp4 >> 16 ) & 0xff; | |
1237 B[3] = p_css_tab1[ B[4] ] ^ k[4] ^ C[4]; | |
1238 k[3] = p_disc_key[2] ^ p_css_tab1[ p_disc_key[3] ] ^ B[3]; | |
1239 B[2] = p_css_tab1[ B[3] ] ^ k[3] ^ C[3]; | |
1240 k[2] = p_disc_key[1] ^ p_css_tab1[ p_disc_key[2] ] ^ B[2]; | |
1241 | |
1242 if( ( B[1] ^ p_css_tab1[ B[2] ] ^ k[ 2 ] ) == C[ 2 ] ) | |
1243 { | |
1244 if( ! investigate( &p_disc_key[0] , &C[0] ) ) | |
1245 { | |
1246 goto end; | |
1247 } | |
1248 } | |
1249 | |
1250 /* Test second possible out2[4] */ | |
1251 out2[4] = ( out2[4] + 0xff ) & 0xff; | |
1252 tmp4 = ( out2[0] << 16 ) | ( out2[1] << 8 ) | out2[4]; | |
1253 tmp4 = BigTable[ tmp4 ]; | |
1254 C[2] = tmp4 & 0xff; | |
1255 C[3] = ( tmp4 >> 8 ) & 0xff; | |
1256 C[4] = ( tmp4 >> 16 ) & 0xff; | |
1257 B[3] = p_css_tab1[ B[4] ] ^ k[4] ^ C[4]; | |
1258 k[3] = p_disc_key[2] ^ p_css_tab1[ p_disc_key[3] ] ^ B[3]; | |
1259 B[2] = p_css_tab1[ B[3] ] ^ k[3] ^ C[3]; | |
1260 k[2] = p_disc_key[1] ^ p_css_tab1[ p_disc_key[2] ] ^ B[2]; | |
1261 | |
1262 if( ( B[1] ^ p_css_tab1[ B[2] ] ^ k[ 2 ] ) == C[ 2 ] ) | |
1263 { | |
1264 if( ! investigate( &p_disc_key[0] , &C[0] ) ) | |
1265 { | |
1266 goto end; | |
1267 } | |
1268 } | |
1269 } | |
1270 } | |
1271 } | |
1272 | |
1273 end: | |
1274 | |
1275 memcpy( p_disc_key, &C[0], KEY_SIZE ); | |
1276 | |
1277 free( K1table ); | |
1278 free( BigTable ); | |
1279 | |
1280 return 0; | |
1281 } | |
1282 | |
1283 /***************************************************************************** | |
1284 * RecoverTitleKey: (title) key recovery from cipher and plain text | |
1285 * Function designed by Frank Stevenson | |
1286 ***************************************************************************** | |
1287 * Called from Attack* which are in turn called by CrackTitleKey. Given | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1288 * a guessed(?) plain text and the cipher text. Returns -1 on failure. |
7027 | 1289 *****************************************************************************/ |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1290 static int RecoverTitleKey( int i_start, uint8_t const *p_crypted, |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1291 uint8_t const *p_decrypted, |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1292 uint8_t const *p_sector_seed, uint8_t *p_key ) |
7027 | 1293 { |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1294 uint8_t p_buffer[10]; |
7027 | 1295 unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6; |
1296 unsigned int i_try; | |
1297 unsigned int i_candidate; | |
1298 unsigned int i, j; | |
1299 int i_exit = -1; | |
1300 | |
1301 for( i = 0 ; i < 10 ; i++ ) | |
1302 { | |
1303 p_buffer[i] = p_css_tab1[p_crypted[i]] ^ p_decrypted[i]; | |
1304 } | |
1305 | |
1306 for( i_try = i_start ; i_try < 0x10000 ; i_try++ ) | |
1307 { | |
1308 i_t1 = i_try >> 8 | 0x100; | |
1309 i_t2 = i_try & 0xff; | |
1310 i_t3 = 0; /* not needed */ | |
1311 i_t5 = 0; | |
1312 | |
1313 /* iterate cipher 4 times to reconstruct LFSR2 */ | |
1314 for( i = 0 ; i < 4 ; i++ ) | |
1315 { | |
1316 /* advance LFSR1 normaly */ | |
1317 i_t4 = p_css_tab2[i_t2] ^ p_css_tab3[i_t1]; | |
1318 i_t2 = i_t1 >> 1; | |
1319 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4; | |
1320 i_t4 = p_css_tab5[i_t4]; | |
1321 /* deduce i_t6 & i_t5 */ | |
1322 i_t6 = p_buffer[i]; | |
1323 if( i_t5 ) | |
1324 { | |
1325 i_t6 = ( i_t6 + 0xff ) & 0x0ff; | |
1326 } | |
1327 if( i_t6 < i_t4 ) | |
1328 { | |
1329 i_t6 += 0x100; | |
1330 } | |
1331 i_t6 -= i_t4; | |
1332 i_t5 += i_t6 + i_t4; | |
1333 i_t6 = p_css_tab4[ i_t6 ]; | |
1334 /* feed / advance i_t3 / i_t5 */ | |
1335 i_t3 = ( i_t3 << 8 ) | i_t6; | |
1336 i_t5 >>= 8; | |
1337 } | |
1338 | |
1339 i_candidate = i_t3; | |
1340 | |
1341 /* iterate 6 more times to validate candidate key */ | |
1342 for( ; i < 10 ; i++ ) | |
1343 { | |
1344 i_t4 = p_css_tab2[i_t2] ^ p_css_tab3[i_t1]; | |
1345 i_t2 = i_t1 >> 1; | |
1346 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4; | |
1347 i_t4 = p_css_tab5[i_t4]; | |
1348 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^ | |
1349 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff; | |
1350 i_t3 = ( i_t3 << 8 ) | i_t6; | |
1351 i_t6 = p_css_tab4[i_t6]; | |
1352 i_t5 += i_t6 + i_t4; | |
1353 if( ( i_t5 & 0xff ) != p_buffer[i] ) | |
1354 { | |
1355 break; | |
1356 } | |
1357 | |
1358 i_t5 >>= 8; | |
1359 } | |
1360 | |
1361 if( i == 10 ) | |
1362 { | |
1363 /* Do 4 backwards steps of iterating t3 to deduce initial state */ | |
1364 i_t3 = i_candidate; | |
1365 for( i = 0 ; i < 4 ; i++ ) | |
1366 { | |
1367 i_t1 = i_t3 & 0xff; | |
1368 i_t3 = ( i_t3 >> 8 ); | |
1369 /* easy to code, and fast enough bruteforce | |
1370 * search for byte shifted in */ | |
1371 for( j = 0 ; j < 256 ; j++ ) | |
1372 { | |
1373 i_t3 = ( i_t3 & 0x1ffff ) | ( j << 17 ); | |
1374 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^ | |
1375 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff; | |
1376 if( i_t6 == i_t1 ) | |
1377 { | |
1378 break; | |
1379 } | |
1380 } | |
1381 } | |
1382 | |
1383 i_t4 = ( i_t3 >> 1 ) - 4; | |
1384 for( i_t5 = 0 ; i_t5 < 8; i_t5++ ) | |
1385 { | |
1386 if( ( ( i_t4 + i_t5 ) * 2 + 8 - ( (i_t4 + i_t5 ) & 7 ) ) | |
1387 == i_t3 ) | |
1388 { | |
1389 p_key[0] = i_try>>8; | |
1390 p_key[1] = i_try & 0xFF; | |
1391 p_key[2] = ( ( i_t4 + i_t5 ) >> 0 ) & 0xFF; | |
1392 p_key[3] = ( ( i_t4 + i_t5 ) >> 8 ) & 0xFF; | |
1393 p_key[4] = ( ( i_t4 + i_t5 ) >> 16 ) & 0xFF; | |
1394 i_exit = i_try + 1; | |
1395 } | |
1396 } | |
1397 } | |
1398 } | |
1399 | |
1400 if( i_exit >= 0 ) | |
1401 { | |
1402 p_key[0] ^= p_sector_seed[0]; | |
1403 p_key[1] ^= p_sector_seed[1]; | |
1404 p_key[2] ^= p_sector_seed[2]; | |
1405 p_key[3] ^= p_sector_seed[3]; | |
1406 p_key[4] ^= p_sector_seed[4]; | |
1407 } | |
1408 | |
1409 return i_exit; | |
1410 } | |
1411 | |
1412 | |
1413 /****************************************************************************** | |
16630 | 1414 * Various pieces for the title crack engine. |
7027 | 1415 ****************************************************************************** |
1416 * The length of the PES packet is located at 0x12-0x13. | |
1417 * The the copyrigth protection bits are located at 0x14 (bits 0x20 and 0x10). | |
1418 * The data of the PES packet begins at 0x15 (if there isn't any PTS/DTS) | |
1419 * or at 0x?? if there are both PTS and DTS's. | |
1420 * The seed value used with the unscrambling key is the 5 bytes at 0x54-0x58. | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1421 * The scrabled part of a sector begins at 0x80. |
7027 | 1422 *****************************************************************************/ |
1423 | |
1424 /* Statistics */ | |
1425 static int i_tries = 0, i_success = 0; | |
1426 | |
1427 /***************************************************************************** | |
1428 * CrackTitleKey: try to crack title key from the contents of a VOB. | |
1429 ***************************************************************************** | |
1430 * This function is called by _dvdcss_titlekey to find a title key, if we've | |
1431 * chosen to crack title key instead of decrypting it with the disc key. | |
1432 * The DVD should have been opened and be in an authenticated state. | |
1433 * i_pos is the starting sector, i_len is the maximum number of sectors to read | |
1434 *****************************************************************************/ | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1435 static int CrackTitleKey( dvdcss_t dvdcss, int i_pos, int i_len, |
7027 | 1436 dvd_key_t p_titlekey ) |
1437 { | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1438 uint8_t p_buf[ DVDCSS_BLOCK_SIZE ]; |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1439 const uint8_t p_packstart[4] = { 0x00, 0x00, 0x01, 0xba }; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1440 int i_reads = 0; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1441 int i_encrypted = 0; |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1442 int b_stop_scanning = 0; |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1443 int b_read_error = 0; |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1444 int i_ret; |
7027 | 1445 |
16630 | 1446 print_debug( dvdcss, "cracking title key at block %i", i_pos ); |
7027 | 1447 |
1448 i_tries = 0; | |
1449 i_success = 0; | |
1450 | |
1451 do | |
1452 { | |
8637
0211de3039eb
update libdvdcss in libmpdvdkit to latest version (1.2.4)
arpi
parents:
8123
diff
changeset
|
1453 i_ret = dvdcss->pf_seek( dvdcss, i_pos ); |
7027 | 1454 |
1455 if( i_ret != i_pos ) | |
1456 { | |
16630 | 1457 print_error( dvdcss, "seek failed" ); |
7027 | 1458 } |
1459 | |
1460 i_ret = dvdcss_read( dvdcss, p_buf, 1, DVDCSS_NOFLAGS ); | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1461 |
7027 | 1462 /* Either we are at the end of the physical device or the auth |
1463 * have failed / were not done and we got a read error. */ | |
1464 if( i_ret <= 0 ) | |
1465 { | |
1466 if( i_ret == 0 ) | |
1467 { | |
16630 | 1468 print_debug( dvdcss, "read returned 0 (end of device?)" ); |
7027 | 1469 } |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1470 else if( !b_read_error ) |
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1471 { |
16630 | 1472 print_debug( dvdcss, "read error at block %i, resorting to " |
1473 "secret arcanes to recover", i_pos ); | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1474 |
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1475 /* Reset the drive before trying to continue */ |
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1476 _dvdcss_close( dvdcss ); |
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1477 _dvdcss_open( dvdcss ); |
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1478 |
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1479 b_read_error = 1; |
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1480 continue; |
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1481 } |
7027 | 1482 break; |
1483 } | |
1484 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1485 /* Stop when we find a non MPEG stream block. |
7027 | 1486 * (We must have reached the end of the stream). |
1487 * For now, allow all blocks that begin with a start code. */ | |
1488 if( memcmp( p_buf, p_packstart, 3 ) ) | |
1489 { | |
16630 | 1490 print_debug( dvdcss, "non MPEG block found at block %i " |
1491 "(end of title)", i_pos ); | |
7027 | 1492 break; |
1493 } | |
1494 | |
1495 if( p_buf[0x0d] & 0x07 ) | |
16630 | 1496 print_debug( dvdcss, "stuffing in pack header" ); |
7027 | 1497 |
1498 /* PES_scrambling_control does not exist in a system_header, | |
1499 * a padding_stream or a private_stream2 (and others?). */ | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1500 if( p_buf[0x14] & 0x30 && ! ( p_buf[0x11] == 0xbb |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1501 || p_buf[0x11] == 0xbe |
7027 | 1502 || p_buf[0x11] == 0xbf ) ) |
1503 { | |
1504 i_encrypted++; | |
1505 | |
1506 if( AttackPattern(p_buf, i_reads, p_titlekey) > 0 ) | |
1507 { | |
1508 b_stop_scanning = 1; | |
1509 } | |
1510 #if 0 | |
1511 if( AttackPadding(p_buf, i_reads, p_titlekey) > 0 ) | |
1512 { | |
1513 b_stop_scanning = 1; | |
1514 } | |
1515 #endif | |
1516 } | |
1517 | |
1518 i_pos++; | |
1519 i_len--; | |
1520 i_reads++; | |
1521 | |
1522 /* Emit a progress indication now and then. */ | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1523 if( !( i_reads & 0xfff ) ) |
7027 | 1524 { |
16630 | 1525 print_debug( dvdcss, "at block %i, still cracking...", i_pos ); |
7027 | 1526 } |
1527 | |
1528 /* Stop after 2000 blocks if we haven't seen any encrypted blocks. */ | |
1529 if( i_reads >= 2000 && i_encrypted == 0 ) break; | |
1530 | |
1531 } while( !b_stop_scanning && i_len > 0); | |
1532 | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1533 if( !b_stop_scanning ) |
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1534 { |
16630 | 1535 print_debug( dvdcss, "end of title reached" ); |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1536 } |
7027 | 1537 |
16630 | 1538 /* Print some statistics. */ |
1539 print_debug( dvdcss, "successful attempts %d/%d, scrambled blocks %d/%d", | |
1540 i_success, i_tries, i_encrypted, i_reads ); | |
7027 | 1541 |
1542 if( i_success > 0 /* b_stop_scanning */ ) | |
1543 { | |
16630 | 1544 print_debug( dvdcss, "vts key initialized" ); |
7027 | 1545 return 1; |
1546 } | |
1547 | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1548 if( i_encrypted == 0 && i_reads > 0 ) |
7027 | 1549 { |
1550 memset( p_titlekey, 0, KEY_SIZE ); | |
16630 | 1551 print_debug( dvdcss, "no scrambled sectors found" ); |
7027 | 1552 return 0; |
1553 } | |
1554 | |
1555 memset( p_titlekey, 0, KEY_SIZE ); | |
1556 return -1; | |
1557 } | |
1558 | |
1559 | |
1560 /****************************************************************************** | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1561 * The original Ethan Hawke (DeCSSPlus) attack (modified). |
7027 | 1562 ****************************************************************************** |
1563 * Tries to find a repeating pattern just before the encrypted part starts. | |
1564 * Then it guesses that the plain text for first encrypted bytes are | |
1565 * a contiuation of that pattern. | |
1566 *****************************************************************************/ | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1567 static int AttackPattern( uint8_t const p_sec[ DVDCSS_BLOCK_SIZE ], |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1568 int i_pos, uint8_t *p_key ) |
7027 | 1569 { |
1570 unsigned int i_best_plen = 0; | |
1571 unsigned int i_best_p = 0; | |
1572 unsigned int i, j; | |
1573 | |
1574 /* For all cycle length from 2 to 48 */ | |
1575 for( i = 2 ; i < 0x30 ; i++ ) | |
1576 { | |
1577 /* Find the number of bytes that repeats in cycles. */ | |
1578 for( j = i + 1; | |
1579 j < 0x80 && ( p_sec[0x7F - (j%i)] == p_sec[0x7F - j] ); | |
1580 j++ ) | |
1581 { | |
1582 /* We have found j repeating bytes with a cycle length i. */ | |
1583 if( j > i_best_plen ) | |
1584 { | |
1585 i_best_plen = j; | |
1586 i_best_p = i; | |
1587 } | |
1588 } | |
1589 } | |
1590 | |
1591 /* We need at most 10 plain text bytes?, so a make sure that we | |
1592 * have at least 20 repeated bytes and that they have cycled at | |
1593 * least one time. */ | |
1594 if( ( i_best_plen > 3 ) && ( i_best_plen / i_best_p >= 2) ) | |
1595 { | |
1596 int res; | |
1597 | |
1598 i_tries++; | |
1599 memset( p_key, 0, KEY_SIZE ); | |
1600 res = RecoverTitleKey( 0, &p_sec[0x80], | |
1601 &p_sec[ 0x80 - (i_best_plen / i_best_p) * i_best_p ], | |
1602 &p_sec[0x54] /* key_seed */, p_key ); | |
1603 i_success += ( res >= 0 ); | |
1604 #if 0 | |
1605 if( res >= 0 ) | |
1606 { | |
1607 fprintf( stderr, "key is %02x:%02x:%02x:%02x:%02x ", | |
1608 p_key[0], p_key[1], p_key[2], p_key[3], p_key[4] ); | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1609 fprintf( stderr, "at block %5d pattern len %3d period %3d %s\n", |
7027 | 1610 i_pos, i_best_plen, i_best_p, (res>=0?"y":"n") ); |
1611 } | |
1612 #endif | |
1613 return ( res >= 0 ); | |
1614 } | |
1615 | |
1616 return 0; | |
1617 } | |
1618 | |
1619 | |
1620 #if 0 | |
1621 /****************************************************************************** | |
1622 * Encrypted Padding_stream attack. | |
1623 ****************************************************************************** | |
1624 * DVD specifies that there must only be one type of data in every sector. | |
1625 * Every sector is one pack and so must obviously be 2048 bytes long. | |
1626 * For the last pice of video data before a VOBU boundary there might not | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1627 * be exactly the right amount of data to fill a sector. Then one has to |
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1628 * pad the pack to 2048 bytes. For just a few bytes this is done in the |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1629 * header but for any large amount you insert a PES packet from the |
7027 | 1630 * Padding stream. This looks like 0x00 00 01 be xx xx ff ff ... |
1631 * where xx xx is the length of the padding stream. | |
1632 *****************************************************************************/ | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1633 static int AttackPadding( uint8_t const p_sec[ DVDCSS_BLOCK_SIZE ], |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1634 int i_pos, uint8_t *p_key ) |
7027 | 1635 { |
1636 unsigned int i_pes_length; | |
1637 /*static int i_tries = 0, i_success = 0;*/ | |
1638 | |
1639 i_pes_length = (p_sec[0x12]<<8) | p_sec[0x13]; | |
1640 | |
1641 /* Coverd by the test below but usfull for debuging. */ | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1642 if( i_pes_length == DVDCSS_BLOCK_SIZE - 0x14 ) return 0; |
7027 | 1643 |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1644 /* There must be room for at least 4? bytes of padding stream, |
7027 | 1645 * and it must be encrypted. |
1646 * sector size - pack/pes header - padding startcode - padding length */ | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1647 if( ( DVDCSS_BLOCK_SIZE - 0x14 - 4 - 2 - i_pes_length < 4 ) || |
7027 | 1648 ( p_sec[0x14 + i_pes_length + 0] == 0x00 && |
1649 p_sec[0x14 + i_pes_length + 1] == 0x00 && | |
1650 p_sec[0x14 + i_pes_length + 2] == 0x01 ) ) | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1651 { |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1652 fprintf( stderr, "plain %d %02x:%02x:%02x:%02x (type %02x sub %02x)\n", |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1653 DVDCSS_BLOCK_SIZE - 0x14 - 4 - 2 - i_pes_length, |
7027 | 1654 p_sec[0x14 + i_pes_length + 0], |
1655 p_sec[0x14 + i_pes_length + 1], | |
1656 p_sec[0x14 + i_pes_length + 2], | |
1657 p_sec[0x14 + i_pes_length + 3], | |
1658 p_sec[0x11], p_sec[0x17 + p_sec[0x16]]); | |
1659 return 0; | |
1660 } | |
1661 | |
1662 /* If we are here we know that there is a where in the pack a | |
10720
f23c35ce0d16
synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our
arpi
parents:
9333
diff
changeset
|
1663 encrypted PES header is (startcode + length). It's never more |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1664 than two packets in the pack, so we 'know' the length. The |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1665 plaintext at offset (0x14 + i_pes_length) will then be |
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1666 00 00 01 e0/bd/be xx xx, in the case of be the following bytes |
7027 | 1667 are also known. */ |
1668 | |
1669 /* An encrypted SPU PES packet with another encrypted PES packet following. | |
1670 Normaly if the following was a padding stream that would be in plain | |
1671 text. So it will be another SPU PES packet. */ | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1672 if( p_sec[0x11] == 0xbd && |
7027 | 1673 p_sec[0x17 + p_sec[0x16]] >= 0x20 && |
1674 p_sec[0x17 + p_sec[0x16]] <= 0x3f ) | |
1675 { | |
1676 i_tries++; | |
1677 } | |
1678 | |
1679 /* A Video PES packet with another encrypted PES packet following. | |
1680 * No reason execpt for time stamps to break the data into two packets. | |
1681 * So it's likely that the following PES packet is a padding stream. */ | |
1682 if( p_sec[0x11] == 0xe0 ) | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1683 { |
7027 | 1684 i_tries++; |
1685 } | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1686 |
7027 | 1687 if( 1 ) |
1688 { | |
1689 /*fprintf( stderr, "key is %02x:%02x:%02x:%02x:%02x ", | |
1690 p_key[0], p_key[1], p_key[2], p_key[3], p_key[4] );*/ | |
1691 fprintf( stderr, "at block %5d padding len %4d " | |
9333
f0f0f176d298
sync with libdvdcss 1.2.5 (including u8->uint8_t and whitespace cosmetics...)
arpi
parents:
8637
diff
changeset
|
1692 "type %02x sub %02x\n", i_pos, i_pes_length, |
7027 | 1693 p_sec[0x11], p_sec[0x17 + p_sec[0x16]]); |
1694 } | |
1695 | |
1696 return 0; | |
1697 } | |
1698 #endif |