annotate libdvdcss/css.c @ 27409:e2de11109139

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