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