comparison libmpdvdkit2/css.c @ 16630:954cdf2171f6

upgrade to libdvdcss 1.2.9
author diego
date Sat, 01 Oct 2005 17:19:33 +0000
parents c2ddedd0619e
children 0af14c5fee82
comparison
equal deleted inserted replaced
16629:045e93202e4a 16630:954cdf2171f6
1 /***************************************************************************** 1 /*****************************************************************************
2 * css.c: Functions for DVD authentication and descrambling 2 * css.c: Functions for DVD authentication and descrambling
3 ***************************************************************************** 3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN 4 * Copyright (C) 1999-2003 VideoLAN
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/
8 * $Id$ 5 * $Id$
9 * 6 *
10 * Author: Stéphane Borel <stef@via.ecp.fr> 7 * Authors: Stéphane Borel <stef@via.ecp.fr>
11 * Håkan Hjort <d95hjort@dtek.chalmers.se> 8 * Håkan Hjort <d95hjort@dtek.chalmers.se>
12 * 9 *
13 * based on: 10 * based on:
14 * - css-auth by Derek Fawcus <derek@spider.com> 11 * - css-auth by Derek Fawcus <derek@spider.com>
15 * - DVD CSS ioctls example program by Andrew T. Veliath <andrewtv@usa.net> 12 * - 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> 13 * - The Divide and conquer attack by Frank A. Stevenson <frank@funcom.com>
14 * (see http://www-2.cs.cmu.edu/~dst/DeCSS/FrankStevenson/index.html)
17 * - DeCSSPlus by Ethan Hawke 15 * - DeCSSPlus by Ethan Hawke
18 * - DecVOB 16 * - DecVOB
19 * see http://www.lemuria.org/DeCSS/ by Tom Vogt for more information. 17 * see http://www.lemuria.org/DeCSS/ by Tom Vogt for more information.
20 * 18 *
21 * This program is free software; you can redistribute it and/or modify 19 * This program is free software; you can redistribute it and/or modify
41 #include <stdio.h> 39 #include <stdio.h>
42 #include <stdlib.h> 40 #include <stdlib.h>
43 #include <string.h> 41 #include <string.h>
44 #include <sys/types.h> 42 #include <sys/types.h>
45 #include <sys/stat.h> 43 #include <sys/stat.h>
44 # include <unistd.h>
46 #include <fcntl.h> 45 #include <fcntl.h>
47 #include <unistd.h> 46 # include <limits.h>
48 #include <limits.h>
49 47
50 #include "dvdcss.h" 48 #include "dvdcss.h"
51 49
52 #include "common.h" 50 #include "common.h"
53 #include "css.h" 51 #include "css.h"
57 #include "device.h" 55 #include "device.h"
58 56
59 /***************************************************************************** 57 /*****************************************************************************
60 * Local prototypes 58 * Local prototypes
61 *****************************************************************************/ 59 *****************************************************************************/
60 static void PrintKey ( dvdcss_t, char *, uint8_t const * );
61
62 static int GetBusKey ( dvdcss_t ); 62 static int GetBusKey ( dvdcss_t );
63 static int GetASF ( dvdcss_t ); 63 static int GetASF ( dvdcss_t );
64 64
65 static void CryptKey ( int, int, uint8_t const *, uint8_t * ); 65 static void CryptKey ( int, int, uint8_t const *, uint8_t * );
66 static void DecryptKey ( uint8_t, 66 static void DecryptKey ( uint8_t,
67 uint8_t const *, uint8_t const *, uint8_t * ); 67 uint8_t const *, uint8_t const *, uint8_t * );
68 68
69 static int DecryptDiscKey ( uint8_t const *, dvd_key_t ); 69 static int DecryptDiscKey ( dvdcss_t, uint8_t const *, dvd_key_t );
70 static int CrackDiscKey ( dvdcss_t, uint8_t * ); 70 static int CrackDiscKey ( dvdcss_t, uint8_t * );
71 71
72 static void DecryptTitleKey ( dvd_key_t, dvd_key_t ); 72 static void DecryptTitleKey ( dvd_key_t, dvd_key_t );
73 static int RecoverTitleKey ( int, uint8_t const *, 73 static int RecoverTitleKey ( int, uint8_t const *,
74 uint8_t const *, uint8_t const *, uint8_t * ); 74 uint8_t const *, uint8_t const *, uint8_t * );
89 i_ret = ioctl_ReadCopyright( dvdcss->i_fd, 0 /* i_layer */, &i_copyright ); 89 i_ret = ioctl_ReadCopyright( dvdcss->i_fd, 0 /* i_layer */, &i_copyright );
90 90
91 #ifdef WIN32 91 #ifdef WIN32
92 if( i_ret < 0 ) 92 if( i_ret < 0 )
93 { 93 {
94 /* Maybe we didn't have enough priviledges to read the copyright 94 /* Maybe we didn't have enough privileges to read the copyright
95 * (see ioctl_ReadCopyright comments). 95 * (see ioctl_ReadCopyright comments).
96 * Apparently, on unencrypted DVDs _dvdcss_disckey() always fails, so 96 * Apparently, on unencrypted DVDs _dvdcss_disckey() always fails, so
97 * we can check this as a work-around. */ 97 * we can check this as a workaround. */
98 i_ret = 0; 98 i_ret = 0;
99 i_copyright = 1;
99 if( _dvdcss_disckey( dvdcss ) < 0 ) 100 if( _dvdcss_disckey( dvdcss ) < 0 )
101 {
100 i_copyright = 0; 102 i_copyright = 0;
101 else 103 }
102 i_copyright = 1;
103 } 104 }
104 #endif 105 #endif
105 106
106 if( i_ret < 0 ) 107 if( i_ret < 0 )
107 { 108 {
108 /* Since it's the first ioctl we try to issue, we add a notice */ 109 /* Since it's the first ioctl we try to issue, we add a notice */
109 _dvdcss_error( dvdcss, "css error: ioctl_ReadCopyright failed, " 110 print_error( dvdcss, "css error: ioctl_ReadCopyright failed, "
110 "make sure there is a DVD in the drive, and that " 111 "make sure there is a DVD in the drive, and that "
111 "you have used the correct device node." ); 112 "you have used the correct device node." );
112 113
113 return i_ret; 114 return i_ret;
114 } 115 }
115 116
116 return i_copyright; 117 return i_copyright;
117 }
118
119 /*****************************************************************************
120 * GetBusKey : Go through the CSS Authentication process
121 *****************************************************************************
122 * It simulates the mutual authentication between logical unit and host,
123 * and stops when a session key (called bus key) has been established.
124 * Always do the full auth sequence. Some drives seem to lie and always
125 * respond with ASF=1. For instance the old DVD roms on Compaq Armada says
126 * that ASF=1 from the start and then later fail with a 'read of scrambled
127 * block without authentication' error.
128 *****************************************************************************/
129 static int GetBusKey( dvdcss_t dvdcss )
130 {
131 uint8_t p_buffer[10];
132 uint8_t p_challenge[2*KEY_SIZE];
133 dvd_key_t p_key1;
134 dvd_key_t p_key2;
135 dvd_key_t p_key_check;
136 uint8_t i_variant = 0;
137 char psz_warning[80];
138 int i_ret = -1;
139 int i;
140
141 _dvdcss_debug( dvdcss, "requesting AGID" );
142 i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
143
144 /* We might have to reset hung authentication processes in the drive
145 by invalidating the corresponding AGID'. As long as we haven't got
146 an AGID, invalidate one (in sequence) and try again. */
147 for( i = 0; i_ret == -1 && i < 4 ; ++i )
148 {
149 sprintf( psz_warning,
150 "ioctl ReportAgid failed, invalidating AGID %d", i );
151 _dvdcss_debug( dvdcss, psz_warning );
152
153 /* This is really _not good_, should be handled by the OS.
154 Invalidating an AGID could make another process fail some
155 where in it's authentication process. */
156 dvdcss->css.i_agid = i;
157 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
158
159 _dvdcss_debug( dvdcss, "requesting AGID" );
160 i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
161 }
162
163 /* Unable to authenticate without AGID */
164 if( i_ret == -1 )
165 {
166 _dvdcss_error( dvdcss, "ioctl ReportAgid failed, fatal" );
167 return -1;
168 }
169
170 /* Setup a challenge, any values should work */
171 for( i = 0 ; i < 10; ++i )
172 {
173 p_challenge[i] = i;
174 }
175
176 /* Get challenge from host */
177 for( i = 0 ; i < 10 ; ++i )
178 {
179 p_buffer[9-i] = p_challenge[i];
180 }
181
182 /* Send challenge to LU */
183 if( ioctl_SendChallenge( dvdcss->i_fd,
184 &dvdcss->css.i_agid, p_buffer ) < 0 )
185 {
186 _dvdcss_error( dvdcss, "ioctl SendChallenge failed" );
187 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
188 return -1;
189 }
190
191 /* Get key1 from LU */
192 if( ioctl_ReportKey1( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0)
193 {
194 _dvdcss_error( dvdcss, "ioctl ReportKey1 failed" );
195 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
196 return -1;
197 }
198
199 /* Send key1 to host */
200 for( i = 0 ; i < KEY_SIZE ; i++ )
201 {
202 p_key1[i] = p_buffer[4-i];
203 }
204
205 for( i = 0 ; i < 32 ; ++i )
206 {
207 CryptKey( 0, i, p_challenge, p_key_check );
208
209 if( memcmp( p_key_check, p_key1, KEY_SIZE ) == 0 )
210 {
211 snprintf( psz_warning, sizeof(psz_warning),
212 "drive authenticated, using variant %d", i );
213 _dvdcss_debug( dvdcss, psz_warning );
214 i_variant = i;
215 break;
216 }
217 }
218
219 if( i == 32 )
220 {
221 _dvdcss_error( dvdcss, "drive would not authenticate" );
222 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
223 return -1;
224 }
225
226 /* Get challenge from LU */
227 if( ioctl_ReportChallenge( dvdcss->i_fd,
228 &dvdcss->css.i_agid, p_buffer ) < 0 )
229 {
230 _dvdcss_error( dvdcss, "ioctl ReportKeyChallenge failed" );
231 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
232 return -1;
233 }
234
235 /* Send challenge to host */
236 for( i = 0 ; i < 10 ; ++i )
237 {
238 p_challenge[i] = p_buffer[9-i];
239 }
240
241 CryptKey( 1, i_variant, p_challenge, p_key2 );
242
243 /* Get key2 from host */
244 for( i = 0 ; i < KEY_SIZE ; ++i )
245 {
246 p_buffer[4-i] = p_key2[i];
247 }
248
249 /* Send key2 to LU */
250 if( ioctl_SendKey2( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
251 {
252 _dvdcss_error( dvdcss, "ioctl SendKey2 failed" );
253 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
254 return -1;
255 }
256
257 /* The drive has accepted us as authentic. */
258 _dvdcss_debug( dvdcss, "authentication established" );
259
260 memcpy( p_challenge, p_key1, KEY_SIZE );
261 memcpy( p_challenge + KEY_SIZE, p_key2, KEY_SIZE );
262
263 CryptKey( 2, i_variant, p_challenge, dvdcss->css.p_bus_key );
264
265 return 0;
266 }
267
268 /*****************************************************************************
269 * PrintKey : debug function that dumps a key value
270 *****************************************************************************/
271 static void PrintKey( dvdcss_t dvdcss, char *prefix, uint8_t const *data )
272 {
273 char psz_output[80];
274
275 sprintf( psz_output, "%s%02x:%02x:%02x:%02x:%02x", prefix,
276 data[0], data[1], data[2], data[3], data[4] );
277 _dvdcss_debug( dvdcss, psz_output );
278 } 118 }
279 119
280 /***************************************************************************** 120 /*****************************************************************************
281 * _dvdcss_title: crack or decrypt the current title key if needed 121 * _dvdcss_title: crack or decrypt the current title key if needed
282 ***************************************************************************** 122 *****************************************************************************
320 i_fd = open( dvdcss->psz_cachefile, O_RDONLY ); 160 i_fd = open( dvdcss->psz_cachefile, O_RDONLY );
321 b_cache = 1; 161 b_cache = 1;
322 162
323 if( i_fd >= 0 ) 163 if( i_fd >= 0 )
324 { 164 {
325 if( read( i_fd, p_title_key, 5 ) == 5 ) 165 unsigned char psz_key[KEY_SIZE * 3];
326 { 166 unsigned int k0, k1, k2, k3, k4;
327 _dvdcss_debug( dvdcss, "key found in cache" ); 167
168 psz_key[KEY_SIZE * 3 - 1] = '\0';
169
170 if( read( i_fd, psz_key, KEY_SIZE * 3 - 1 ) == KEY_SIZE * 3 - 1
171 && sscanf( psz_key, "%x:%x:%x:%x:%x",
172 &k0, &k1, &k2, &k3, &k4 ) == 5 )
173 {
174 p_title_key[0] = k0;
175 p_title_key[1] = k1;
176 p_title_key[2] = k2;
177 p_title_key[3] = k3;
178 p_title_key[4] = k4;
179 PrintKey( dvdcss, "title key found in cache ", p_title_key );
180
328 /* Don't try to save it again */ 181 /* Don't try to save it again */
329 b_cache = 0; 182 b_cache = 0;
330 i_ret = 1; 183 i_ret = 1;
331 } 184 }
185
332 close( i_fd ); 186 close( i_fd );
333 } 187 }
334 } 188 }
335 189
336 /* Crack or decrypt CSS title key for current VTS */ 190 /* Crack or decrypt CSS title key for current VTS */
338 { 192 {
339 i_ret = _dvdcss_titlekey( dvdcss, i_block, p_title_key ); 193 i_ret = _dvdcss_titlekey( dvdcss, i_block, p_title_key );
340 194
341 if( i_ret < 0 ) 195 if( i_ret < 0 )
342 { 196 {
343 _dvdcss_error( dvdcss, "fatal error in vts css key" ); 197 print_error( dvdcss, "fatal error in vts css key" );
344 return i_ret; 198 return i_ret;
345 } 199 }
346 200
347 if( i_ret == 0 ) 201 if( i_ret == 0 )
348 { 202 {
349 _dvdcss_debug( dvdcss, "unencrypted title" ); 203 print_debug( dvdcss, "unencrypted title" );
350 /* We cache this anyway, so we don't need to check again. */ 204 /* We cache this anyway, so we don't need to check again. */
351 } 205 }
352 } 206 }
353 207
354 /* Key is valid, we store it on disk. */ 208 /* Key is valid, we store it on disk. */
355 if( b_cache ) 209 if( dvdcss->psz_cachefile[0] && b_cache )
356 { 210 {
357 i_fd = open( dvdcss->psz_cachefile, O_RDWR|O_CREAT|O_EXCL, 0644 ); 211 i_fd = open( dvdcss->psz_cachefile, O_RDWR|O_CREAT, 0644 );
358 if( i_fd >= 0 ) 212 if( i_fd >= 0 )
359 { 213 {
360 write( i_fd, p_title_key, 5 ); 214 unsigned char psz_key[KEY_SIZE * 3 + 2];
215
216 sprintf( psz_key, "%02x:%02x:%02x:%02x:%02x\r\n",
217 p_title_key[0], p_title_key[1], p_title_key[2],
218 p_title_key[3], p_title_key[4] );
219
220 write( i_fd, psz_key, KEY_SIZE * 3 + 1 );
361 close( i_fd ); 221 close( i_fd );
362 } 222 }
363 } 223 }
364 224
365 /* Find our spot in the list */ 225 /* Find our spot in the list */
418 } 278 }
419 279
420 /* Get encrypted disc key */ 280 /* Get encrypted disc key */
421 if( ioctl_ReadDiscKey( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 ) 281 if( ioctl_ReadDiscKey( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
422 { 282 {
423 _dvdcss_error( dvdcss, "ioctl ReadDiscKey failed" ); 283 print_error( dvdcss, "ioctl ReadDiscKey failed" );
424 return -1; 284 return -1;
425 } 285 }
426 286
427 /* This should have invaidated the AGID and got us ASF=1. */ 287 /* This should have invaidated the AGID and got us ASF=1. */
428 if( GetASF( dvdcss ) != 1 ) 288 if( GetASF( dvdcss ) != 1 )
429 { 289 {
430 /* Region mismatch (or region not set) is the most likely source. */ 290 /* Region mismatch (or region not set) is the most likely source. */
431 _dvdcss_error( dvdcss, 291 print_error( dvdcss,
432 "ASF not 1 after reading disc key (region mismatch?)" ); 292 "ASF not 1 after reading disc key (region mismatch?)" );
433 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); 293 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
434 return -1; 294 return -1;
435 } 295 }
436 296
437 /* Decrypt disc key using bus key */ 297 /* Shuffle disc key using bus key */
438 for( i = 0 ; i < DVD_DISCKEY_SIZE ; i++ ) 298 for( i = 0 ; i < DVD_DISCKEY_SIZE ; i++ )
439 { 299 {
440 p_buffer[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ]; 300 p_buffer[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ];
441 } 301 }
442 302
303 /* Decrypt disc key */
443 switch( dvdcss->i_method ) 304 switch( dvdcss->i_method )
444 { 305 {
445 case DVDCSS_METHOD_KEY: 306 case DVDCSS_METHOD_KEY:
446 307
447 /* Decrypt disc key with player key. */ 308 /* Decrypt disc key with player key. */
448 _dvdcss_debug( dvdcss, "decrypting disc key with player keys" ); 309 PrintKey( dvdcss, "decrypting disc key ", p_buffer );
449 if( ! DecryptDiscKey( p_buffer, p_disc_key ) ) 310 if( ! DecryptDiscKey( dvdcss, p_buffer, p_disc_key ) )
450 { 311 {
451 PrintKey( dvdcss, "decrypted disc key is ", p_disc_key ); 312 PrintKey( dvdcss, "decrypted disc key is ", p_disc_key );
452 break; 313 break;
453 } 314 }
454 _dvdcss_debug( dvdcss, "failed to decrypt the disc key, " 315 print_debug( dvdcss, "failed to decrypt the disc key, "
455 "faulty drive/kernel? " 316 "faulty drive/kernel? "
456 "cracking title keys instead" ); 317 "cracking title keys instead" );
457 318
458 /* Fallback, but not to DISC as the disc key might be faulty */ 319 /* Fallback, but not to DISC as the disc key might be faulty */
459 dvdcss->i_method = DVDCSS_METHOD_TITLE; 320 dvdcss->i_method = DVDCSS_METHOD_TITLE;
460 break; 321 break;
461 322
462 case DVDCSS_METHOD_DISC: 323 case DVDCSS_METHOD_DISC:
463 324
464 /* Crack Disc key to be able to use it */ 325 /* Crack Disc key to be able to use it */
465 _dvdcss_debug( dvdcss, "cracking disc key from key hash ..."
466 " this will take some time" );
467 memcpy( p_disc_key, p_buffer, KEY_SIZE ); 326 memcpy( p_disc_key, p_buffer, KEY_SIZE );
327 PrintKey( dvdcss, "cracking disc key ", p_disc_key );
468 if( ! CrackDiscKey( dvdcss, p_disc_key ) ) 328 if( ! CrackDiscKey( dvdcss, p_disc_key ) )
469 { 329 {
470 PrintKey( dvdcss, "cracked disc key is ", p_disc_key ); 330 PrintKey( dvdcss, "cracked disc key is ", p_disc_key );
471 break; 331 break;
472 } 332 }
473 _dvdcss_debug( dvdcss, "failed to crack the disc key" ); 333 print_debug( dvdcss, "failed to crack the disc key" );
474 memset( p_disc_key, 0, KEY_SIZE ); 334 memset( p_disc_key, 0, KEY_SIZE );
475 dvdcss->i_method = DVDCSS_METHOD_TITLE; 335 dvdcss->i_method = DVDCSS_METHOD_TITLE;
476 break; 336 break;
477 337
478 default: 338 default:
479 339
480 _dvdcss_debug( dvdcss, "disc key needs not be decrypted" ); 340 print_debug( dvdcss, "disc key needs not be decrypted" );
481 memset( p_disc_key, 0, KEY_SIZE ); 341 memset( p_disc_key, 0, KEY_SIZE );
482 break; 342 break;
483 } 343 }
484 344
485 memcpy( dvdcss->css.p_disc_key, p_disc_key, KEY_SIZE ); 345 memcpy( dvdcss->css.p_disc_key, p_disc_key, KEY_SIZE );
502 { 362 {
503 /* We have a decrypted Disc key and the ioctls are available, 363 /* We have a decrypted Disc key and the ioctls are available,
504 * read the title key and decrypt it. 364 * read the title key and decrypt it.
505 */ 365 */
506 366
507 _dvdcss_debug( dvdcss, "getting title key the classic way" ); 367 print_debug( dvdcss, "getting title key at block %i the classic way",
368 i_pos );
508 369
509 /* We need to authenticate again every time to get a new session key */ 370 /* We need to authenticate again every time to get a new session key */
510 if( GetBusKey( dvdcss ) < 0 ) 371 if( GetBusKey( dvdcss ) < 0 )
511 { 372 {
512 return -1; 373 return -1;
514 375
515 /* Get encrypted title key */ 376 /* Get encrypted title key */
516 if( ioctl_ReadTitleKey( dvdcss->i_fd, &dvdcss->css.i_agid, 377 if( ioctl_ReadTitleKey( dvdcss->i_fd, &dvdcss->css.i_agid,
517 i_pos, p_key ) < 0 ) 378 i_pos, p_key ) < 0 )
518 { 379 {
519 _dvdcss_debug( dvdcss, 380 print_debug( dvdcss,
520 "ioctl ReadTitleKey failed (region mismatch?)" ); 381 "ioctl ReadTitleKey failed (region mismatch?)" );
521 i_ret = -1; 382 i_ret = -1;
522 } 383 }
523 384
524 /* Test ASF, it will be reset to 0 if we got a Region error */ 385 /* Test ASF, it will be reset to 0 if we got a Region error */
525 switch( GetASF( dvdcss ) ) 386 switch( GetASF( dvdcss ) )
526 { 387 {
527 case -1: 388 case -1:
528 /* An error getting the ASF status, something must be wrong. */ 389 /* An error getting the ASF status, something must be wrong. */
529 _dvdcss_debug( dvdcss, "lost ASF requesting title key" ); 390 print_debug( dvdcss, "lost ASF requesting title key" );
530 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); 391 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
531 i_ret = -1; 392 i_ret = -1;
532 break; 393 break;
533 394
534 case 0: 395 case 0:
535 /* This might either be a title that has no key, 396 /* This might either be a title that has no key,
536 * or we encountered a region error. */ 397 * or we encountered a region error. */
537 _dvdcss_debug( dvdcss, "lost ASF requesting title key" ); 398 print_debug( dvdcss, "lost ASF requesting title key" );
538 break; 399 break;
539 400
540 case 1: 401 case 1:
541 /* Drive status is ok. */ 402 /* Drive status is ok. */
542 /* If the title key request failed, but we did not loose ASF, 403 /* If the title key request failed, but we did not loose ASF,
563 { 424 {
564 i_ret = 0; 425 i_ret = 0;
565 } 426 }
566 else 427 else
567 { 428 {
429 PrintKey( dvdcss, "initial disc key ", dvdcss->css.p_disc_key );
568 DecryptTitleKey( dvdcss->css.p_disc_key, p_key ); 430 DecryptTitleKey( dvdcss->css.p_disc_key, p_key );
431 PrintKey( dvdcss, "decrypted title key ", p_key );
569 i_ret = 1; 432 i_ret = 1;
570 } 433 }
571 434
572 /* All went well either there wasn't a key or we have it now. */ 435 /* All went well either there wasn't a key or we have it now. */
573 memcpy( p_title_key, p_key, KEY_SIZE ); 436 memcpy( p_title_key, p_key, KEY_SIZE );
575 438
576 return i_ret; 439 return i_ret;
577 } 440 }
578 441
579 /* The title key request failed */ 442 /* The title key request failed */
580 _dvdcss_debug( dvdcss, "resetting drive and cracking title key" ); 443 print_debug( dvdcss, "resetting drive and cracking title key" );
581 444
582 /* Read an unscrambled sector and reset the drive */ 445 /* Read an unscrambled sector and reset the drive */
583 dvdcss->pf_seek( dvdcss, 0 ); 446 dvdcss->pf_seek( dvdcss, 0 );
584 dvdcss->pf_read( dvdcss, p_garbage, 1 ); 447 dvdcss->pf_read( dvdcss, p_garbage, 1 );
585 dvdcss->pf_seek( dvdcss, 0 ); 448 dvdcss->pf_seek( dvdcss, 0 );
610 { 473 {
611 unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6; 474 unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
612 uint8_t *p_end = p_sec + DVDCSS_BLOCK_SIZE; 475 uint8_t *p_end = p_sec + DVDCSS_BLOCK_SIZE;
613 476
614 /* PES_scrambling_control */ 477 /* PES_scrambling_control */
615 if( p_sec[0x14] & 0x30) 478 if( !(p_sec[0x14] & 0x30) )
616 { 479 {
617 i_t1 = (p_key[0] ^ p_sec[0x54]) | 0x100; 480 return 0;
618 i_t2 = p_key[1] ^ p_sec[0x55]; 481 }
619 i_t3 = (p_key[2] | (p_key[3] << 8) | 482
620 (p_key[4] << 16)) ^ (p_sec[0x56] | 483 i_t1 = (p_key[0] ^ p_sec[0x54]) | 0x100;
621 (p_sec[0x57] << 8) | (p_sec[0x58] << 16)); 484 i_t2 = p_key[1] ^ p_sec[0x55];
622 i_t4 = i_t3 & 7; 485 i_t3 = (p_key[2] | (p_key[3] << 8) |
623 i_t3 = i_t3 * 2 + 8 - i_t4; 486 (p_key[4] << 16)) ^ (p_sec[0x56] |
624 p_sec += 0x80; 487 (p_sec[0x57] << 8) | (p_sec[0x58] << 16));
625 i_t5 = 0; 488 i_t4 = i_t3 & 7;
626 489 i_t3 = i_t3 * 2 + 8 - i_t4;
627 while( p_sec != p_end ) 490 p_sec += 0x80;
628 { 491 i_t5 = 0;
629 i_t4 = p_css_tab2[i_t2] ^ p_css_tab3[i_t1]; 492
630 i_t2 = i_t1>>1; 493 while( p_sec != p_end )
631 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4; 494 {
632 i_t4 = p_css_tab5[i_t4]; 495 i_t4 = p_css_tab2[i_t2] ^ p_css_tab3[i_t1];
633 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^ 496 i_t2 = i_t1>>1;
634 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff; 497 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
635 i_t3 = (i_t3 << 8 ) | i_t6; 498 i_t4 = p_css_tab5[i_t4];
636 i_t6 = p_css_tab4[i_t6]; 499 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
637 i_t5 += i_t6 + i_t4; 500 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
638 *p_sec = p_css_tab1[*p_sec] ^ ( i_t5 & 0xff ); 501 i_t3 = (i_t3 << 8 ) | i_t6;
639 p_sec++; 502 i_t6 = p_css_tab4[i_t6];
640 i_t5 >>= 8; 503 i_t5 += i_t6 + i_t4;
641 } 504 *p_sec = p_css_tab1[*p_sec] ^ ( i_t5 & 0xff );
505 p_sec++;
506 i_t5 >>= 8;
642 } 507 }
643 508
644 return 0; 509 return 0;
645 } 510 }
646 511
647 /* Following functions are local */ 512 /* Following functions are local */
513
514 /*****************************************************************************
515 * GetBusKey : Go through the CSS Authentication process
516 *****************************************************************************
517 * It simulates the mutual authentication between logical unit and host,
518 * and stops when a session key (called bus key) has been established.
519 * Always do the full auth sequence. Some drives seem to lie and always
520 * respond with ASF=1. For instance the old DVD roms on Compaq Armada says
521 * that ASF=1 from the start and then later fail with a 'read of scrambled
522 * block without authentication' error.
523 *****************************************************************************/
524 static int GetBusKey( dvdcss_t dvdcss )
525 {
526 uint8_t p_buffer[10];
527 uint8_t p_challenge[2*KEY_SIZE];
528 dvd_key_t p_key1;
529 dvd_key_t p_key2;
530 dvd_key_t p_key_check;
531 uint8_t i_variant = 0;
532 int i_ret = -1;
533 int i;
534
535 print_debug( dvdcss, "requesting AGID" );
536 i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
537
538 /* We might have to reset hung authentication processes in the drive
539 * by invalidating the corresponding AGID'. As long as we haven't got
540 * an AGID, invalidate one (in sequence) and try again. */
541 for( i = 0; i_ret == -1 && i < 4 ; ++i )
542 {
543 print_debug( dvdcss, "ioctl ReportAgid failed, "
544 "invalidating AGID %d", i );
545
546 /* This is really _not good_, should be handled by the OS.
547 * Invalidating an AGID could make another process fail somewhere
548 * in its authentication process. */
549 dvdcss->css.i_agid = i;
550 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
551
552 print_debug( dvdcss, "requesting AGID" );
553 i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
554 }
555
556 /* Unable to authenticate without AGID */
557 if( i_ret == -1 )
558 {
559 print_error( dvdcss, "ioctl ReportAgid failed, fatal" );
560 return -1;
561 }
562
563 /* Setup a challenge, any values should work */
564 for( i = 0 ; i < 10; ++i )
565 {
566 p_challenge[i] = i;
567 }
568
569 /* Get challenge from host */
570 for( i = 0 ; i < 10 ; ++i )
571 {
572 p_buffer[9-i] = p_challenge[i];
573 }
574
575 /* Send challenge to LU */
576 if( ioctl_SendChallenge( dvdcss->i_fd,
577 &dvdcss->css.i_agid, p_buffer ) < 0 )
578 {
579 print_error( dvdcss, "ioctl SendChallenge failed" );
580 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
581 return -1;
582 }
583
584 /* Get key1 from LU */
585 if( ioctl_ReportKey1( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0)
586 {
587 print_error( dvdcss, "ioctl ReportKey1 failed" );
588 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
589 return -1;
590 }
591
592 /* Send key1 to host */
593 for( i = 0 ; i < KEY_SIZE ; i++ )
594 {
595 p_key1[i] = p_buffer[4-i];
596 }
597
598 for( i = 0 ; i < 32 ; ++i )
599 {
600 CryptKey( 0, i, p_challenge, p_key_check );
601
602 if( memcmp( p_key_check, p_key1, KEY_SIZE ) == 0 )
603 {
604 print_debug( dvdcss, "drive authenticated, using variant %d", i );
605 i_variant = i;
606 break;
607 }
608 }
609
610 if( i == 32 )
611 {
612 print_error( dvdcss, "drive would not authenticate" );
613 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
614 return -1;
615 }
616
617 /* Get challenge from LU */
618 if( ioctl_ReportChallenge( dvdcss->i_fd,
619 &dvdcss->css.i_agid, p_buffer ) < 0 )
620 {
621 print_error( dvdcss, "ioctl ReportKeyChallenge failed" );
622 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
623 return -1;
624 }
625
626 /* Send challenge to host */
627 for( i = 0 ; i < 10 ; ++i )
628 {
629 p_challenge[i] = p_buffer[9-i];
630 }
631
632 CryptKey( 1, i_variant, p_challenge, p_key2 );
633
634 /* Get key2 from host */
635 for( i = 0 ; i < KEY_SIZE ; ++i )
636 {
637 p_buffer[4-i] = p_key2[i];
638 }
639
640 /* Send key2 to LU */
641 if( ioctl_SendKey2( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
642 {
643 print_error( dvdcss, "ioctl SendKey2 failed" );
644 ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
645 return -1;
646 }
647
648 /* The drive has accepted us as authentic. */
649 print_debug( dvdcss, "authentication established" );
650
651 memcpy( p_challenge, p_key1, KEY_SIZE );
652 memcpy( p_challenge + KEY_SIZE, p_key2, KEY_SIZE );
653
654 CryptKey( 2, i_variant, p_challenge, dvdcss->css.p_bus_key );
655
656 return 0;
657 }
658
659 /*****************************************************************************
660 * PrintKey : debug function that dumps a key value
661 *****************************************************************************/
662 static void PrintKey( dvdcss_t dvdcss, char *prefix, uint8_t const *data )
663 {
664 print_debug( dvdcss, "%s%02x:%02x:%02x:%02x:%02x", prefix,
665 data[0], data[1], data[2], data[3], data[4] );
666 }
648 667
649 /***************************************************************************** 668 /*****************************************************************************
650 * GetASF : Get Authentication success flag 669 * GetASF : Get Authentication success flag
651 ***************************************************************************** 670 *****************************************************************************
652 * Returns : 671 * Returns :
659 int i_asf = 0; 678 int i_asf = 0;
660 679
661 if( ioctl_ReportASF( dvdcss->i_fd, NULL, &i_asf ) != 0 ) 680 if( ioctl_ReportASF( dvdcss->i_fd, NULL, &i_asf ) != 0 )
662 { 681 {
663 /* The ioctl process has failed */ 682 /* The ioctl process has failed */
664 _dvdcss_error( dvdcss, "GetASF fatal error" ); 683 print_error( dvdcss, "GetASF fatal error" );
665 return -1; 684 return -1;
666 } 685 }
667 686
668 if( i_asf ) 687 if( i_asf )
669 { 688 {
670 _dvdcss_debug( dvdcss, "GetASF authenticated, ASF=1" ); 689 print_debug( dvdcss, "GetASF authenticated, ASF=1" );
671 } 690 }
672 else 691 else
673 { 692 {
674 _dvdcss_debug( dvdcss, "GetASF not authenticated, ASF=0" ); 693 print_debug( dvdcss, "GetASF not authenticated, ASF=0" );
675 } 694 }
676 695
677 return i_asf; 696 return i_asf;
678 } 697 }
679 698
943 962
944 return; 963 return;
945 } 964 }
946 965
947 /***************************************************************************** 966 /*****************************************************************************
967 * player_keys: alternate DVD player keys
968 *****************************************************************************
969 * These player keys were generated using Frank A. Stevenson's PlayerKey
970 * cracker. A copy of his article can be found here:
971 * http://www-2.cs.cmu.edu/~dst/DeCSS/FrankStevenson/mail2.txt
972 *****************************************************************************/
973 static const dvd_key_t player_keys[] =
974 {
975 { 0x01, 0xaf, 0xe3, 0x12, 0x80 },
976 { 0x12, 0x11, 0xca, 0x04, 0x3b },
977 { 0x14, 0x0c, 0x9e, 0xd0, 0x09 },
978 { 0x14, 0x71, 0x35, 0xba, 0xe2 },
979 { 0x1a, 0xa4, 0x33, 0x21, 0xa6 },
980 { 0x26, 0xec, 0xc4, 0xa7, 0x4e },
981 { 0x2c, 0xb2, 0xc1, 0x09, 0xee },
982 { 0x2f, 0x25, 0x9e, 0x96, 0xdd },
983 { 0x33, 0x2f, 0x49, 0x6c, 0xe0 },
984 { 0x35, 0x5b, 0xc1, 0x31, 0x0f },
985 { 0x36, 0x67, 0xb2, 0xe3, 0x85 },
986 { 0x39, 0x3d, 0xf1, 0xf1, 0xbd },
987 { 0x3b, 0x31, 0x34, 0x0d, 0x91 },
988 { 0x45, 0xed, 0x28, 0xeb, 0xd3 },
989 { 0x48, 0xb7, 0x6c, 0xce, 0x69 },
990 { 0x4b, 0x65, 0x0d, 0xc1, 0xee },
991 { 0x4c, 0xbb, 0xf5, 0x5b, 0x23 },
992 { 0x51, 0x67, 0x67, 0xc5, 0xe0 },
993 { 0x53, 0x94, 0xe1, 0x75, 0xbf },
994 { 0x57, 0x2c, 0x8b, 0x31, 0xae },
995 { 0x63, 0xdb, 0x4c, 0x5b, 0x4a },
996 { 0x7b, 0x1e, 0x5e, 0x2b, 0x57 },
997 { 0x85, 0xf3, 0x85, 0xa0, 0xe0 },
998 { 0xab, 0x1e, 0xe7, 0x7b, 0x72 },
999 { 0xab, 0x36, 0xe3, 0xeb, 0x76 },
1000 { 0xb1, 0xb8, 0xf9, 0x38, 0x03 },
1001 { 0xb8, 0x5d, 0xd8, 0x53, 0xbd },
1002 { 0xbf, 0x92, 0xc3, 0xb0, 0xe2 },
1003 { 0xcf, 0x1a, 0xb2, 0xf8, 0x0a },
1004 { 0xec, 0xa0, 0xcf, 0xb3, 0xff },
1005 { 0xfc, 0x95, 0xa9, 0x87, 0x35 }
1006 };
1007
1008 /*****************************************************************************
948 * DecryptDiscKey 1009 * DecryptDiscKey
949 ***************************************************************************** 1010 *****************************************************************************
950 * Decryption of the disc key with player keys if they are available. 1011 * Decryption of the disc key with player keys: try to decrypt the disc key
951 * Try to decrypt the disc key from every position with every player key. 1012 * from every position with every player key.
952 * p_struct_disckey: the 2048 byte DVD_STRUCT_DISCKEY data 1013 * p_struct_disckey: the 2048 byte DVD_STRUCT_DISCKEY data
953 * p_disc_key: result, the 5 byte disc key 1014 * p_disc_key: result, the 5 byte disc key
954 *****************************************************************************/ 1015 *****************************************************************************/
955 static int DecryptDiscKey( uint8_t const *p_struct_disckey, 1016 static int DecryptDiscKey( dvdcss_t dvdcss, uint8_t const *p_struct_disckey,
956 dvd_key_t p_disc_key ) 1017 dvd_key_t p_disc_key )
957 { 1018 {
958 uint8_t p_verify[KEY_SIZE]; 1019 uint8_t p_verify[KEY_SIZE];
959 unsigned int i, n = 0; 1020 unsigned int i, n = 0;
960 1021
961 static const dvd_key_t player_keys[] =
962 {
963 { 0x01, 0xaf, 0xe3, 0x12, 0x80 },
964 { 0x12, 0x11, 0xca, 0x04, 0x3b },
965 { 0x14, 0x0c, 0x9e, 0xd0, 0x09 },
966 { 0x14, 0x71, 0x35, 0xba, 0xe2 },
967 { 0x1a, 0xa4, 0x33, 0x21, 0xa6 },
968 { 0x26, 0xec, 0xc4, 0xa7, 0x4e },
969 { 0x2c, 0xb2, 0xc1, 0x09, 0xee },
970 { 0x2f, 0x25, 0x9e, 0x96, 0xdd },
971 { 0x33, 0x2f, 0x49, 0x6c, 0xe0 },
972 { 0x35, 0x5b, 0xc1, 0x31, 0x0f },
973 { 0x36, 0x67, 0xb2, 0xe3, 0x85 },
974 { 0x39, 0x3d, 0xf1, 0xf1, 0xbd },
975 { 0x3b, 0x31, 0x34, 0x0d, 0x91 },
976 { 0x45, 0xed, 0x28, 0xeb, 0xd3 },
977 { 0x48, 0xb7, 0x6c, 0xce, 0x69 },
978 { 0x4b, 0x65, 0x0d, 0xc1, 0xee },
979 { 0x4c, 0xbb, 0xf5, 0x5b, 0x23 },
980 { 0x51, 0x67, 0x67, 0xc5, 0xe0 },
981 { 0x53, 0x94, 0xe1, 0x75, 0xbf },
982 { 0x57, 0x2c, 0x8b, 0x31, 0xae },
983 { 0x63, 0xdb, 0x4c, 0x5b, 0x4a },
984 { 0x7b, 0x1e, 0x5e, 0x2b, 0x57 },
985 { 0x85, 0xf3, 0x85, 0xa0, 0xe0 },
986 { 0xab, 0x1e, 0xe7, 0x7b, 0x72 },
987 { 0xab, 0x36, 0xe3, 0xeb, 0x76 },
988 { 0xb1, 0xb8, 0xf9, 0x38, 0x03 },
989 { 0xb8, 0x5d, 0xd8, 0x53, 0xbd },
990 { 0xbf, 0x92, 0xc3, 0xb0, 0xe2 },
991 { 0xcf, 0x1a, 0xb2, 0xf8, 0x0a },
992 { 0xec, 0xa0, 0xcf, 0xb3, 0xff },
993 { 0xfc, 0x95, 0xa9, 0x87, 0x35 }
994 };
995
996 /* Decrypt disc key with the above player keys */ 1022 /* Decrypt disc key with the above player keys */
997 while( n < sizeof(player_keys) / sizeof(dvd_key_t) ) 1023 for( n = 0; n < sizeof(player_keys) / sizeof(dvd_key_t); n++ )
998 { 1024 {
1025 PrintKey( dvdcss, "trying player key ", player_keys[n] );
1026
999 for( i = 1; i < 409; i++ ) 1027 for( i = 1; i < 409; i++ )
1000 { 1028 {
1001 /* Check if player key n is the right key for position i. */ 1029 /* Check if player key n is the right key for position i. */
1002 DecryptKey( 0, player_keys[n], p_struct_disckey + 5 * i, 1030 DecryptKey( 0, player_keys[n], p_struct_disckey + 5 * i,
1003 p_disc_key ); 1031 p_disc_key );
1011 if( memcmp( p_disc_key, p_verify, KEY_SIZE ) == 0 ) 1039 if( memcmp( p_disc_key, p_verify, KEY_SIZE ) == 0 )
1012 { 1040 {
1013 return 0; 1041 return 0;
1014 } 1042 }
1015 } 1043 }
1016 n++;
1017 } 1044 }
1018 1045
1019 /* Have tried all combinations of positions and keys, 1046 /* Have tried all combinations of positions and keys,
1020 * and we still didn't succeed. */ 1047 * and we still didn't succeed. */
1021 memset( p_disc_key, 0, KEY_SIZE ); 1048 memset( p_disc_key, 0, KEY_SIZE );
1074 unsigned int nPossibleK1; /* #of possible K[1] values */ 1101 unsigned int nPossibleK1; /* #of possible K[1] values */
1075 unsigned char* K1table; /* Lookup table for possible K[1] */ 1102 unsigned char* K1table; /* Lookup table for possible K[1] */
1076 unsigned int* BigTable; /* LFSR2 startstate indexed by 1103 unsigned int* BigTable; /* LFSR2 startstate indexed by
1077 * 1,2,5 output byte */ 1104 * 1,2,5 output byte */
1078 1105
1079 _dvdcss_debug( dvdcss, "cracking disc key" );
1080
1081 /* 1106 /*
1082 * Prepare tables for hash reversal 1107 * Prepare tables for hash reversal
1083 */ 1108 */
1084
1085 1109
1086 /* initialize lookup tables for k[1] */ 1110 /* initialize lookup tables for k[1] */
1087 K1table = malloc( 65536 * K1TABLEWIDTH ); 1111 K1table = malloc( 65536 * K1TABLEWIDTH );
1088 memset( K1table, 0 , 65536 * K1TABLEWIDTH ); 1112 memset( K1table, 0 , 65536 * K1TABLEWIDTH );
1089 if( K1table == NULL ) 1113 if( K1table == NULL )
1102 tmp4 = K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) ]; /* count of entries here */ 1126 tmp4 = K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) ]; /* count of entries here */
1103 tmp4++; 1127 tmp4++;
1104 /* 1128 /*
1105 if( tmp4 == K1TABLEWIDTH ) 1129 if( tmp4 == K1TABLEWIDTH )
1106 { 1130 {
1107 _dvdcss_debug( dvdcss, "Table disaster %d", tmp4 ); 1131 print_debug( dvdcss, "Table disaster %d", tmp4 );
1108 } 1132 }
1109 */ 1133 */
1110 if( tmp4 < K1TABLEWIDTH ) 1134 if( tmp4 < K1TABLEWIDTH )
1111 { 1135 {
1112 K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) + tmp4 ] = i; 1136 K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) + tmp4 ] = i;
1123 return -1; 1147 return -1;
1124 } 1148 }
1125 1149
1126 tmp3 = 0; 1150 tmp3 = 0;
1127 1151
1128 _dvdcss_debug( dvdcss, "initializing the big table" ); 1152 print_debug( dvdcss, "initializing the big table" );
1129 1153
1130 for( i = 0 ; i < 16777216 ; i++ ) 1154 for( i = 0 ; i < 16777216 ; i++ )
1131 { 1155 {
1132 tmp = (( i + i ) & 0x1fffff0 ) | 0x8 | ( i & 0x7 ); 1156 tmp = (( i + i ) & 0x1fffff0 ) | 0x8 | ( i & 0x7 );
1133 1157
1374 return i_exit; 1398 return i_exit;
1375 } 1399 }
1376 1400
1377 1401
1378 /****************************************************************************** 1402 /******************************************************************************
1379 * Various pices for the title crack engine. 1403 * Various pieces for the title crack engine.
1380 ****************************************************************************** 1404 ******************************************************************************
1381 * The length of the PES packet is located at 0x12-0x13. 1405 * The length of the PES packet is located at 0x12-0x13.
1382 * The the copyrigth protection bits are located at 0x14 (bits 0x20 and 0x10). 1406 * The the copyrigth protection bits are located at 0x14 (bits 0x20 and 0x10).
1383 * The data of the PES packet begins at 0x15 (if there isn't any PTS/DTS) 1407 * The data of the PES packet begins at 0x15 (if there isn't any PTS/DTS)
1384 * or at 0x?? if there are both PTS and DTS's. 1408 * or at 0x?? if there are both PTS and DTS's.
1406 int i_encrypted = 0; 1430 int i_encrypted = 0;
1407 int b_stop_scanning = 0; 1431 int b_stop_scanning = 0;
1408 int b_read_error = 0; 1432 int b_read_error = 0;
1409 int i_ret; 1433 int i_ret;
1410 1434
1411 _dvdcss_debug( dvdcss, "cracking title key" ); 1435 print_debug( dvdcss, "cracking title key at block %i", i_pos );
1412 1436
1413 i_tries = 0; 1437 i_tries = 0;
1414 i_success = 0; 1438 i_success = 0;
1415 1439
1416 do 1440 do
1417 { 1441 {
1418 i_ret = dvdcss->pf_seek( dvdcss, i_pos ); 1442 i_ret = dvdcss->pf_seek( dvdcss, i_pos );
1419 1443
1420 if( i_ret != i_pos ) 1444 if( i_ret != i_pos )
1421 { 1445 {
1422 _dvdcss_error( dvdcss, "seek failed" ); 1446 print_error( dvdcss, "seek failed" );
1423 } 1447 }
1424 1448
1425 i_ret = dvdcss_read( dvdcss, p_buf, 1, DVDCSS_NOFLAGS ); 1449 i_ret = dvdcss_read( dvdcss, p_buf, 1, DVDCSS_NOFLAGS );
1426 1450
1427 /* Either we are at the end of the physical device or the auth 1451 /* Either we are at the end of the physical device or the auth
1428 * have failed / were not done and we got a read error. */ 1452 * have failed / were not done and we got a read error. */
1429 if( i_ret <= 0 ) 1453 if( i_ret <= 0 )
1430 { 1454 {
1431 if( i_ret == 0 ) 1455 if( i_ret == 0 )
1432 { 1456 {
1433 _dvdcss_debug( dvdcss, "read returned 0 (end of device?)" ); 1457 print_debug( dvdcss, "read returned 0 (end of device?)" );
1434 } 1458 }
1435 else if( !b_read_error ) 1459 else if( !b_read_error )
1436 { 1460 {
1437 _dvdcss_debug( dvdcss, "read error, resorting to secret " 1461 print_debug( dvdcss, "read error at block %i, resorting to "
1438 "arcanes to recover" ); 1462 "secret arcanes to recover", i_pos );
1439 1463
1440 /* Reset the drive before trying to continue */ 1464 /* Reset the drive before trying to continue */
1441 _dvdcss_close( dvdcss ); 1465 _dvdcss_close( dvdcss );
1442 _dvdcss_open( dvdcss ); 1466 _dvdcss_open( dvdcss );
1443 1467
1450 /* Stop when we find a non MPEG stream block. 1474 /* Stop when we find a non MPEG stream block.
1451 * (We must have reached the end of the stream). 1475 * (We must have reached the end of the stream).
1452 * For now, allow all blocks that begin with a start code. */ 1476 * For now, allow all blocks that begin with a start code. */
1453 if( memcmp( p_buf, p_packstart, 3 ) ) 1477 if( memcmp( p_buf, p_packstart, 3 ) )
1454 { 1478 {
1455 _dvdcss_debug( dvdcss, "non MPEG block found (end of title)" ); 1479 print_debug( dvdcss, "non MPEG block found at block %i "
1480 "(end of title)", i_pos );
1456 break; 1481 break;
1457 } 1482 }
1458 1483
1459 if( p_buf[0x0d] & 0x07 ) 1484 if( p_buf[0x0d] & 0x07 )
1460 _dvdcss_debug( dvdcss, "stuffing in pack header" ); 1485 print_debug( dvdcss, "stuffing in pack header" );
1461 1486
1462 /* PES_scrambling_control does not exist in a system_header, 1487 /* PES_scrambling_control does not exist in a system_header,
1463 * a padding_stream or a private_stream2 (and others?). */ 1488 * a padding_stream or a private_stream2 (and others?). */
1464 if( p_buf[0x14] & 0x30 && ! ( p_buf[0x11] == 0xbb 1489 if( p_buf[0x14] & 0x30 && ! ( p_buf[0x11] == 0xbb
1465 || p_buf[0x11] == 0xbe 1490 || p_buf[0x11] == 0xbe
1484 i_reads++; 1509 i_reads++;
1485 1510
1486 /* Emit a progress indication now and then. */ 1511 /* Emit a progress indication now and then. */
1487 if( !( i_reads & 0xfff ) ) 1512 if( !( i_reads & 0xfff ) )
1488 { 1513 {
1489 _dvdcss_debug( dvdcss, "still cracking..." ); 1514 print_debug( dvdcss, "at block %i, still cracking...", i_pos );
1490 } 1515 }
1491 1516
1492 /* Stop after 2000 blocks if we haven't seen any encrypted blocks. */ 1517 /* Stop after 2000 blocks if we haven't seen any encrypted blocks. */
1493 if( i_reads >= 2000 && i_encrypted == 0 ) break; 1518 if( i_reads >= 2000 && i_encrypted == 0 ) break;
1494 1519
1495 } while( !b_stop_scanning && i_len > 0); 1520 } while( !b_stop_scanning && i_len > 0);
1496 1521
1497 if( !b_stop_scanning ) 1522 if( !b_stop_scanning )
1498 { 1523 {
1499 _dvdcss_debug( dvdcss, "end of title reached" ); 1524 print_debug( dvdcss, "end of title reached" );
1500 } 1525 }
1501 1526
1502 { /* Print some statistics. */ 1527 /* Print some statistics. */
1503 char psz_info[128]; 1528 print_debug( dvdcss, "successful attempts %d/%d, scrambled blocks %d/%d",
1504 snprintf( psz_info, sizeof(psz_info), 1529 i_success, i_tries, i_encrypted, i_reads );
1505 "%d of %d attempts successful, %d of %d blocks scrambled",
1506 i_success, i_tries, i_encrypted, i_reads );
1507 _dvdcss_debug( dvdcss, psz_info );
1508 }
1509 1530
1510 if( i_success > 0 /* b_stop_scanning */ ) 1531 if( i_success > 0 /* b_stop_scanning */ )
1511 { 1532 {
1512 _dvdcss_debug( dvdcss, "vts key initialized" ); 1533 print_debug( dvdcss, "vts key initialized" );
1513 return 1; 1534 return 1;
1514 } 1535 }
1515 1536
1516 if( i_encrypted == 0 && i_reads > 0 ) 1537 if( i_encrypted == 0 && i_reads > 0 )
1517 { 1538 {
1518 memset( p_titlekey, 0, KEY_SIZE ); 1539 memset( p_titlekey, 0, KEY_SIZE );
1519 _dvdcss_debug( dvdcss, "file was unscrambled" ); 1540 print_debug( dvdcss, "no scrambled sectors found" );
1520 return 0; 1541 return 0;
1521 } 1542 }
1522 1543
1523 memset( p_titlekey, 0, KEY_SIZE ); 1544 memset( p_titlekey, 0, KEY_SIZE );
1524 return -1; 1545 return -1;