1 /*****************************************************************************
2 * dvd_css.c: Functions for DVD authentification and unscrambling
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: dvd_css.c,v 1.12 2001/02/20 07:49:12 sam Exp $
7 * Author: Stéphane Borel <stef@via.ecp.fr>
10 * - css-auth by Derek Fawcus <derek@spider.com>
11 * - DVD CSS ioctls example program by Andrew T. Veliath <andrewtv@usa.net>
12 * - The Divide and conquer attack by Frank A. Stevenson<frank@funcom.com>
13 * - DeCSSPlus by Ethan Hawke
15 * see http://www.lemuria.org/DeCSS/ by Tom Vogt for more information.
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
30 *****************************************************************************/
32 /*****************************************************************************
34 *****************************************************************************/
37 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD ) || defined( SYS_BEOS )
43 #include <netinet/in.h>
44 #ifdef HAVE_SYS_IOCTL_H
45 # include <sys/ioctl.h>
47 #ifdef HAVE_SYS_DVDIO_H
48 # include <sys/dvdio.h>
51 # include <linux/cdrom.h>
59 #include "dvd_ioctl.h"
62 #include "input_dvd.h"
64 /*****************************************************************************
66 *****************************************************************************/
67 static u8 pi_css_tab1[256]=
68 { 0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76,
69 0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b,
70 0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96,
71 0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b,
72 0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12,
73 0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f,
74 0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90,
75 0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91,
76 0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74,
77 0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75,
78 0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94,
79 0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95,
80 0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10,
81 0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11,
82 0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92,
83 0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f,
84 0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16,
85 0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b,
86 0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6,
87 0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb,
88 0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72,
89 0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f,
90 0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0,
91 0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1,
92 0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14,
93 0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15,
94 0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4,
95 0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5,
96 0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70,
97 0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71,
98 0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2,
99 0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff
102 static u8 pi_css_tab2[256]=
103 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
104 0x09, 0x08, 0x0b, 0x0a, 0x0d, 0x0c, 0x0f, 0x0e,
105 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15,
106 0x1b, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x1d, 0x1c,
107 0x24, 0x25, 0x26, 0x27, 0x20, 0x21, 0x22, 0x23,
108 0x2d, 0x2c, 0x2f, 0x2e, 0x29, 0x28, 0x2b, 0x2a,
109 0x36, 0x37, 0x34, 0x35, 0x32, 0x33, 0x30, 0x31,
110 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
111 0x49, 0x48, 0x4b, 0x4a, 0x4d, 0x4c, 0x4f, 0x4e,
112 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
113 0x5b, 0x5a, 0x59, 0x58, 0x5f, 0x5e, 0x5d, 0x5c,
114 0x52, 0x53, 0x50, 0x51, 0x56, 0x57, 0x54, 0x55,
115 0x6d, 0x6c, 0x6f, 0x6e, 0x69, 0x68, 0x6b, 0x6a,
116 0x64, 0x65, 0x66, 0x67, 0x60, 0x61, 0x62, 0x63,
117 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
118 0x76, 0x77, 0x74, 0x75, 0x72, 0x73, 0x70, 0x71,
119 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95,
120 0x9b, 0x9a, 0x99, 0x98, 0x9f, 0x9e, 0x9d, 0x9c,
121 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
122 0x89, 0x88, 0x8b, 0x8a, 0x8d, 0x8c, 0x8f, 0x8e,
123 0xb6, 0xb7, 0xb4, 0xb5, 0xb2, 0xb3, 0xb0, 0xb1,
124 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
125 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3,
126 0xad, 0xac, 0xaf, 0xae, 0xa9, 0xa8, 0xab, 0xaa,
127 0xdb, 0xda, 0xd9, 0xd8, 0xdf, 0xde, 0xdd, 0xdc,
128 0xd2, 0xd3, 0xd0, 0xd1, 0xd6, 0xd7, 0xd4, 0xd5,
129 0xc9, 0xc8, 0xcb, 0xca, 0xcd, 0xcc, 0xcf, 0xce,
130 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
131 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
132 0xf6, 0xf7, 0xf4, 0xf5, 0xf2, 0xf3, 0xf0, 0xf1,
133 0xed, 0xec, 0xef, 0xee, 0xe9, 0xe8, 0xeb, 0xea,
134 0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3
137 static u8 pi_css_tab3[512]=
138 { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
139 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
140 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
141 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
142 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
143 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
144 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
145 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
146 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
147 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
148 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
149 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
150 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
151 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
152 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
153 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
154 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
155 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
156 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
157 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
158 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
159 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
160 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
161 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
162 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
163 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
164 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
165 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
166 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
167 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
168 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
169 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
170 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
171 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
172 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
173 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
174 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
175 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
176 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
177 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
178 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
179 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
180 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
181 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
182 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
183 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
184 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
185 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
186 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
187 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
188 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
189 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
190 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
191 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
192 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
193 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
194 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
195 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
196 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
197 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
198 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
199 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
200 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
201 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff
204 static u8 pi_css_tab4[256]=
205 { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
206 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
207 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
208 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
209 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
210 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
211 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
212 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
213 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
214 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
215 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
216 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
217 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
218 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
219 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
220 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
221 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
222 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
223 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
224 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
225 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
226 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
227 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
228 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
229 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
230 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
231 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
232 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
233 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
234 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
235 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
236 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
239 static u8 pi_css_tab5[256]=
240 { 0xff, 0x7f, 0xbf, 0x3f, 0xdf, 0x5f, 0x9f, 0x1f,
241 0xef, 0x6f, 0xaf, 0x2f, 0xcf, 0x4f, 0x8f, 0x0f,
242 0xf7, 0x77, 0xb7, 0x37, 0xd7, 0x57, 0x97, 0x17,
243 0xe7, 0x67, 0xa7, 0x27, 0xc7, 0x47, 0x87, 0x07,
244 0xfb, 0x7b, 0xbb, 0x3b, 0xdb, 0x5b, 0x9b, 0x1b,
245 0xeb, 0x6b, 0xab, 0x2b, 0xcb, 0x4b, 0x8b, 0x0b,
246 0xf3, 0x73, 0xb3, 0x33, 0xd3, 0x53, 0x93, 0x13,
247 0xe3, 0x63, 0xa3, 0x23, 0xc3, 0x43, 0x83, 0x03,
248 0xfd, 0x7d, 0xbd, 0x3d, 0xdd, 0x5d, 0x9d, 0x1d,
249 0xed, 0x6d, 0xad, 0x2d, 0xcd, 0x4d, 0x8d, 0x0d,
250 0xf5, 0x75, 0xb5, 0x35, 0xd5, 0x55, 0x95, 0x15,
251 0xe5, 0x65, 0xa5, 0x25, 0xc5, 0x45, 0x85, 0x05,
252 0xf9, 0x79, 0xb9, 0x39, 0xd9, 0x59, 0x99, 0x19,
253 0xe9, 0x69, 0xa9, 0x29, 0xc9, 0x49, 0x89, 0x09,
254 0xf1, 0x71, 0xb1, 0x31, 0xd1, 0x51, 0x91, 0x11,
255 0xe1, 0x61, 0xa1, 0x21, 0xc1, 0x41, 0x81, 0x01,
256 0xfe, 0x7e, 0xbe, 0x3e, 0xde, 0x5e, 0x9e, 0x1e,
257 0xee, 0x6e, 0xae, 0x2e, 0xce, 0x4e, 0x8e, 0x0e,
258 0xf6, 0x76, 0xb6, 0x36, 0xd6, 0x56, 0x96, 0x16,
259 0xe6, 0x66, 0xa6, 0x26, 0xc6, 0x46, 0x86, 0x06,
260 0xfa, 0x7a, 0xba, 0x3a, 0xda, 0x5a, 0x9a, 0x1a,
261 0xea, 0x6a, 0xaa, 0x2a, 0xca, 0x4a, 0x8a, 0x0a,
262 0xf2, 0x72, 0xb2, 0x32, 0xd2, 0x52, 0x92, 0x12,
263 0xe2, 0x62, 0xa2, 0x22, 0xc2, 0x42, 0x82, 0x02,
264 0xfc, 0x7c, 0xbc, 0x3c, 0xdc, 0x5c, 0x9c, 0x1c,
265 0xec, 0x6c, 0xac, 0x2c, 0xcc, 0x4c, 0x8c, 0x0c,
266 0xf4, 0x74, 0xb4, 0x34, 0xd4, 0x54, 0x94, 0x14,
267 0xe4, 0x64, 0xa4, 0x24, 0xc4, 0x44, 0x84, 0x04,
268 0xf8, 0x78, 0xb8, 0x38, 0xd8, 0x58, 0x98, 0x18,
269 0xe8, 0x68, 0xa8, 0x28, 0xc8, 0x48, 0x88, 0x08,
270 0xf0, 0x70, 0xb0, 0x30, 0xd0, 0x50, 0x90, 0x10,
271 0xe0, 0x60, 0xa0, 0x20, 0xc0, 0x40, 0x80, 0x00
274 static u8 pi_crypt_tab0[256] = {
275 0xB7, 0xF4, 0x82, 0x57, 0xDA, 0x4D, 0xDB, 0xE2,
276 0x2F, 0x52, 0x1A, 0xA8, 0x68, 0x5A, 0x8A, 0xFF,
277 0xFB, 0x0E, 0x6D, 0x35, 0xF7, 0x5C, 0x76, 0x12,
278 0xCE, 0x25, 0x79, 0x29, 0x39, 0x62, 0x08, 0x24,
279 0xA5, 0x85, 0x7B, 0x56, 0x01, 0x23, 0x68, 0xCF,
280 0x0A, 0xE2, 0x5A, 0xED, 0x3D, 0x59, 0xB0, 0xA9,
281 0xB0, 0x2C, 0xF2, 0xB8, 0xEF, 0x32, 0xA9, 0x40,
282 0x80, 0x71, 0xAF, 0x1E, 0xDE, 0x8F, 0x58, 0x88,
283 0xB8, 0x3A, 0xD0, 0xFC, 0xC4, 0x1E, 0xB5, 0xA0,
284 0xBB, 0x3B, 0x0F, 0x01, 0x7E, 0x1F, 0x9F, 0xD9,
285 0xAA, 0xB8, 0x3D, 0x9D, 0x74, 0x1E, 0x25, 0xDB,
286 0x37, 0x56, 0x8F, 0x16, 0xBA, 0x49, 0x2B, 0xAC,
287 0xD0, 0xBD, 0x95, 0x20, 0xBE, 0x7A, 0x28, 0xD0,
288 0x51, 0x64, 0x63, 0x1C, 0x7F, 0x66, 0x10, 0xBB,
289 0xC4, 0x56, 0x1A, 0x04, 0x6E, 0x0A, 0xEC, 0x9C,
290 0xD6, 0xE8, 0x9A, 0x7A, 0xCF, 0x8C, 0xDB, 0xB1,
291 0xEF, 0x71, 0xDE, 0x31, 0xFF, 0x54, 0x3E, 0x5E,
292 0x07, 0x69, 0x96, 0xB0, 0xCF, 0xDD, 0x9E, 0x47,
293 0xC7, 0x96, 0x8F, 0xE4, 0x2B, 0x59, 0xC6, 0xEE,
294 0xB9, 0x86, 0x9A, 0x64, 0x84, 0x72, 0xE2, 0x5B,
295 0xA2, 0x96, 0x58, 0x99, 0x50, 0x03, 0xF5, 0x38,
296 0x4D, 0x02, 0x7D, 0xE7, 0x7D, 0x75, 0xA7, 0xB8,
297 0x67, 0x87, 0x84, 0x3F, 0x1D, 0x11, 0xE5, 0xFC,
298 0x1E, 0xD3, 0x83, 0x16, 0xA5, 0x29, 0xF6, 0xC7,
299 0x15, 0x61, 0x29, 0x1A, 0x43, 0x4F, 0x9B, 0xAF,
300 0xC5, 0x87, 0x34, 0x6C, 0x0F, 0x3B, 0xA8, 0x1D,
301 0x45, 0x58, 0x25, 0xDC, 0xA8, 0xA3, 0x3B, 0xD1,
302 0x79, 0x1B, 0x48, 0xF2, 0xE9, 0x93, 0x1F, 0xFC,
303 0xDB, 0x2A, 0x90, 0xA9, 0x8A, 0x3D, 0x39, 0x18,
304 0xA3, 0x8E, 0x58, 0x6C, 0xE0, 0x12, 0xBB, 0x25,
305 0xCD, 0x71, 0x22, 0xA2, 0x64, 0xC6, 0xE7, 0xFB,
306 0xAD, 0x94, 0x77, 0x04, 0x9A, 0x39, 0xCF, 0x7C};
308 static u8 pi_crypt_tab1[256] = {
309 0x8C, 0x47, 0xB0, 0xE1, 0xEB, 0xFC, 0xEB, 0x56,
310 0x10, 0xE5, 0x2C, 0x1A, 0x5D, 0xEF, 0xBE, 0x4F,
311 0x08, 0x75, 0x97, 0x4B, 0x0E, 0x25, 0x8E, 0x6E,
312 0x39, 0x5A, 0x87, 0x53, 0xC4, 0x1F, 0xF4, 0x5C,
313 0x4E, 0xE6, 0x99, 0x30, 0xE0, 0x42, 0x88, 0xAB,
314 0xE5, 0x85, 0xBC, 0x8F, 0xD8, 0x3C, 0x54, 0xC9,
315 0x53, 0x47, 0x18, 0xD6, 0x06, 0x5B, 0x41, 0x2C,
316 0x67, 0x1E, 0x41, 0x74, 0x33, 0xE2, 0xB4, 0xE0,
317 0x23, 0x29, 0x42, 0xEA, 0x55, 0x0F, 0x25, 0xB4,
318 0x24, 0x2C, 0x99, 0x13, 0xEB, 0x0A, 0x0B, 0xC9,
319 0xF9, 0x63, 0x67, 0x43, 0x2D, 0xC7, 0x7D, 0x07,
320 0x60, 0x89, 0xD1, 0xCC, 0xE7, 0x94, 0x77, 0x74,
321 0x9B, 0x7E, 0xD7, 0xE6, 0xFF, 0xBB, 0x68, 0x14,
322 0x1E, 0xA3, 0x25, 0xDE, 0x3A, 0xA3, 0x54, 0x7B,
323 0x87, 0x9D, 0x50, 0xCA, 0x27, 0xC3, 0xA4, 0x50,
324 0x91, 0x27, 0xD4, 0xB0, 0x82, 0x41, 0x97, 0x79,
325 0x94, 0x82, 0xAC, 0xC7, 0x8E, 0xA5, 0x4E, 0xAA,
326 0x78, 0x9E, 0xE0, 0x42, 0xBA, 0x28, 0xEA, 0xB7,
327 0x74, 0xAD, 0x35, 0xDA, 0x92, 0x60, 0x7E, 0xD2,
328 0x0E, 0xB9, 0x24, 0x5E, 0x39, 0x4F, 0x5E, 0x63,
329 0x09, 0xB5, 0xFA, 0xBF, 0xF1, 0x22, 0x55, 0x1C,
330 0xE2, 0x25, 0xDB, 0xC5, 0xD8, 0x50, 0x03, 0x98,
331 0xC4, 0xAC, 0x2E, 0x11, 0xB4, 0x38, 0x4D, 0xD0,
332 0xB9, 0xFC, 0x2D, 0x3C, 0x08, 0x04, 0x5A, 0xEF,
333 0xCE, 0x32, 0xFB, 0x4C, 0x92, 0x1E, 0x4B, 0xFB,
334 0x1A, 0xD0, 0xE2, 0x3E, 0xDA, 0x6E, 0x7C, 0x4D,
335 0x56, 0xC3, 0x3F, 0x42, 0xB1, 0x3A, 0x23, 0x4D,
336 0x6E, 0x84, 0x56, 0x68, 0xF4, 0x0E, 0x03, 0x64,
337 0xD0, 0xA9, 0x92, 0x2F, 0x8B, 0xBC, 0x39, 0x9C,
338 0xAC, 0x09, 0x5E, 0xEE, 0xE5, 0x97, 0xBF, 0xA5,
339 0xCE, 0xFA, 0x28, 0x2C, 0x6D, 0x4F, 0xEF, 0x77,
340 0xAA, 0x1B, 0x79, 0x8E, 0x97, 0xB4, 0xC3, 0xF4};
342 static u8 pi_crypt_tab2[256] = {
343 0xB7, 0x75, 0x81, 0xD5, 0xDC, 0xCA, 0xDE, 0x66,
344 0x23, 0xDF, 0x15, 0x26, 0x62, 0xD1, 0x83, 0x77,
345 0xE3, 0x97, 0x76, 0xAF, 0xE9, 0xC3, 0x6B, 0x8E,
346 0xDA, 0xB0, 0x6E, 0xBF, 0x2B, 0xF1, 0x19, 0xB4,
347 0x95, 0x34, 0x48, 0xE4, 0x37, 0x94, 0x5D, 0x7B,
348 0x36, 0x5F, 0x65, 0x53, 0x07, 0xE2, 0x89, 0x11,
349 0x98, 0x85, 0xD9, 0x12, 0xC1, 0x9D, 0x84, 0xEC,
350 0xA4, 0xD4, 0x88, 0xB8, 0xFC, 0x2C, 0x79, 0x28,
351 0xD8, 0xDB, 0xB3, 0x1E, 0xA2, 0xF9, 0xD0, 0x44,
352 0xD7, 0xD6, 0x60, 0xEF, 0x14, 0xF4, 0xF6, 0x31,
353 0xD2, 0x41, 0x46, 0x67, 0x0A, 0xE1, 0x58, 0x27,
354 0x43, 0xA3, 0xF8, 0xE0, 0xC8, 0xBA, 0x5A, 0x5C,
355 0x80, 0x6C, 0xC6, 0xF2, 0xE8, 0xAD, 0x7D, 0x04,
356 0x0D, 0xB9, 0x3C, 0xC2, 0x25, 0xBD, 0x49, 0x63,
357 0x8C, 0x9F, 0x51, 0xCE, 0x20, 0xC5, 0xA1, 0x50,
358 0x92, 0x2D, 0xDD, 0xBC, 0x8D, 0x4F, 0x9A, 0x71,
359 0x2F, 0x30, 0x1D, 0x73, 0x39, 0x13, 0xFB, 0x1A,
360 0xCB, 0x24, 0x59, 0xFE, 0x05, 0x96, 0x57, 0x0F,
361 0x1F, 0xCF, 0x54, 0xBE, 0xF5, 0x06, 0x1B, 0xB2,
362 0x6D, 0xD3, 0x4D, 0x32, 0x56, 0x21, 0x33, 0x0B,
363 0x52, 0xE7, 0xAB, 0xEB, 0xA6, 0x74, 0x00, 0x4C,
364 0xB1, 0x7F, 0x82, 0x99, 0x87, 0x0E, 0x5E, 0xC0,
365 0x8F, 0xEE, 0x6F, 0x55, 0xF3, 0x7E, 0x08, 0x90,
366 0xFA, 0xB6, 0x64, 0x70, 0x47, 0x4A, 0x17, 0xA7,
367 0xB5, 0x40, 0x8A, 0x38, 0xE5, 0x68, 0x3E, 0x8B,
368 0x69, 0xAA, 0x9B, 0x42, 0xA5, 0x10, 0x01, 0x35,
369 0xFD, 0x61, 0x9E, 0xE6, 0x16, 0x9C, 0x86, 0xED,
370 0xCD, 0x2E, 0xFF, 0xC4, 0x5B, 0xA0, 0xAE, 0xCC,
371 0x4B, 0x3B, 0x03, 0xBB, 0x1C, 0x2A, 0xAC, 0x0C,
372 0x3F, 0x93, 0xC7, 0x72, 0x7A, 0x09, 0x22, 0x3D,
373 0x45, 0x78, 0xA9, 0xA8, 0xEA, 0xC9, 0x6A, 0xF7,
374 0x29, 0x91, 0xF0, 0x02, 0x18, 0x3A, 0x4E, 0x7C};
376 static u8 pi_crypt_tab3[288] = {
377 0x73, 0x51, 0x95, 0xE1, 0x12, 0xE4, 0xC0, 0x58,
378 0xEE, 0xF2, 0x08, 0x1B, 0xA9, 0xFA, 0x98, 0x4C,
379 0xA7, 0x33, 0xE2, 0x1B, 0xA7, 0x6D, 0xF5, 0x30,
380 0x97, 0x1D, 0xF3, 0x02, 0x60, 0x5A, 0x82, 0x0F,
381 0x91, 0xD0, 0x9C, 0x10, 0x39, 0x7A, 0x83, 0x85,
382 0x3B, 0xB2, 0xB8, 0xAE, 0x0C, 0x09, 0x52, 0xEA,
383 0x1C, 0xE1, 0x8D, 0x66, 0x4F, 0xF3, 0xDA, 0x92,
384 0x29, 0xB9, 0xD5, 0xC5, 0x77, 0x47, 0x22, 0x53,
385 0x14, 0xF7, 0xAF, 0x22, 0x64, 0xDF, 0xC6, 0x72,
386 0x12, 0xF3, 0x75, 0xDA, 0xD7, 0xD7, 0xE5, 0x02,
387 0x9E, 0xED, 0xDA, 0xDB, 0x4C, 0x47, 0xCE, 0x91,
388 0x06, 0x06, 0x6D, 0x55, 0x8B, 0x19, 0xC9, 0xEF,
389 0x8C, 0x80, 0x1A, 0x0E, 0xEE, 0x4B, 0xAB, 0xF2,
390 0x08, 0x5C, 0xE9, 0x37, 0x26, 0x5E, 0x9A, 0x90,
391 0x00, 0xF3, 0x0D, 0xB2, 0xA6, 0xA3, 0xF7, 0x26,
392 0x17, 0x48, 0x88, 0xC9, 0x0E, 0x2C, 0xC9, 0x02,
393 0xE7, 0x18, 0x05, 0x4B, 0xF3, 0x39, 0xE1, 0x20,
394 0x02, 0x0D, 0x40, 0xC7, 0xCA, 0xB9, 0x48, 0x30,
395 0x57, 0x67, 0xCC, 0x06, 0xBF, 0xAC, 0x81, 0x08,
396 0x24, 0x7A, 0xD4, 0x8B, 0x19, 0x8E, 0xAC, 0xB4,
397 0x5A, 0x0F, 0x73, 0x13, 0xAC, 0x9E, 0xDA, 0xB6,
398 0xB8, 0x96, 0x5B, 0x60, 0x88, 0xE1, 0x81, 0x3F,
399 0x07, 0x86, 0x37, 0x2D, 0x79, 0x14, 0x52, 0xEA,
400 0x73, 0xDF, 0x3D, 0x09, 0xC8, 0x25, 0x48, 0xD8,
401 0x75, 0x60, 0x9A, 0x08, 0x27, 0x4A, 0x2C, 0xB9,
402 0xA8, 0x8B, 0x8A, 0x73, 0x62, 0x37, 0x16, 0x02,
403 0xBD, 0xC1, 0x0E, 0x56, 0x54, 0x3E, 0x14, 0x5F,
404 0x8C, 0x8F, 0x6E, 0x75, 0x1C, 0x07, 0x39, 0x7B,
405 0x4B, 0xDB, 0xD3, 0x4B, 0x1E, 0xC8, 0x7E, 0xFE,
406 0x3E, 0x72, 0x16, 0x83, 0x7D, 0xEE, 0xF5, 0xCA,
407 0xC5, 0x18, 0xF9, 0xD8, 0x68, 0xAB, 0x38, 0x85,
408 0xA8, 0xF0, 0xA1, 0x73, 0x9F, 0x5D, 0x19, 0x0B,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x33, 0x72, 0x39, 0x25, 0x67, 0x26, 0x6D, 0x71,
411 0x36, 0x77, 0x3C, 0x20, 0x62, 0x23, 0x68, 0x74,
412 0xC3, 0x82, 0xC9, 0x15, 0x57, 0x16, 0x5D, 0x81};
417 /*****************************************************************************
418 * CSSGetASF : Get Authentification success flag
422 * 0 if the device needs to be authenticated,
424 *****************************************************************************/
425 static int CSSGetASF( int i_fd )
427 dvd_authinfo auth_info;
429 auth_info.type = DVD_LU_SEND_ASF;
430 auth_info.lsasf.asf = 0;
432 for( auth_info.lsasf.agid = 0 ; auth_info.lsasf.agid < 4 ;
433 auth_info.lsasf.agid++ )
435 if( !( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) ) )
437 intf_WarnMsg( 3, "CSS: %sAuthenticated",
438 ( auth_info.lsasf.asf ) ? "" : "not " );
439 return auth_info.lsasf.asf;
443 /* The ioctl process has failed */
444 intf_ErrMsg( "CSS: GetASF Fatal Error" );
448 /*****************************************************************************
449 * CSSCryptKey : shuffles bits and unencrypt keys.
450 * Used during authentication and disc key negociation in CSSInit.
452 * i_key_type : 0->key1, 1->key2, 2->buskey.
453 * i_varient : between 0 and 31.
454 *****************************************************************************/
455 static void CSSCryptKey( int i_key_type, int i_varient,
456 u8 const * pi_challenge, u8* pi_key )
458 /* Permutation table for challenge */
459 u8 ppi_perm_challenge[3][10] =
460 { { 1, 3, 0, 7, 5, 2, 9, 6, 4, 8 },
461 { 6, 1, 9, 3, 8, 5, 7, 4, 0, 2 },
462 { 4, 0, 3, 5, 7, 2, 8, 6, 1, 9 } };
464 /* Permutation table for varient table for key2 and buskey */
465 u8 ppi_perm_varient[2][32] =
466 { { 0x0a, 0x08, 0x0e, 0x0c, 0x0b, 0x09, 0x0f, 0x0d,
467 0x1a, 0x18, 0x1e, 0x1c, 0x1b, 0x19, 0x1f, 0x1d,
468 0x02, 0x00, 0x06, 0x04, 0x03, 0x01, 0x07, 0x05,
469 0x12, 0x10, 0x16, 0x14, 0x13, 0x11, 0x17, 0x15 },
470 { 0x12, 0x1a, 0x16, 0x1e, 0x02, 0x0a, 0x06, 0x0e,
471 0x10, 0x18, 0x14, 0x1c, 0x00, 0x08, 0x04, 0x0c,
472 0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f,
473 0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d } };
476 { 0xB7, 0x74, 0x85, 0xD0, 0xCC, 0xDB, 0xCA, 0x73,
477 0x03, 0xFE, 0x31, 0x03, 0x52, 0xE0, 0xB7, 0x42,
478 0x63, 0x16, 0xF2, 0x2A, 0x79, 0x52, 0xFF, 0x1B,
479 0x7A, 0x11, 0xCA, 0x1A, 0x9B, 0x40, 0xAD, 0x01 };
481 /* The "secret" key */
482 u8 pi_secret[5] = { 0x55, 0xD6, 0xC4, 0xC5, 0x28 };
488 u8 i_lfsr0_o; /* 1 bit used */
489 u8 i_lfsr1_o; /* 1 bit used */
502 for (i = 9; i >= 0; --i)
503 pi_scratch[i] = pi_challenge[ppi_perm_challenge[i_key_type][i]];
505 i_css_varient = ( i_key_type == 0 ) ? i_varient :
506 ppi_perm_varient[i_key_type-1][i_varient];
509 * This encryption engine implements one of 32 variations
510 * one the same theme depending upon the choice in the
511 * varient parameter (0 - 31).
513 * The algorithm itself manipulates a 40 bit input into
515 * The parameter 'input' is 80 bits. It consists of
516 * the 40 bit input value that is to be encrypted followed
517 * by a 40 bit seed value for the pseudo random number
521 /* Feed the secret into the input values such that
522 * we alter the seed to the LFSR's used above, then
523 * generate the bits to play with.
525 for( i = 5 ; --i >= 0 ; )
527 pi_tmp1[i] = pi_scratch[5 + i] ^ pi_secret[i] ^ pi_crypt_tab2[i];
531 * We use two LFSR's (seeded from some of the input data bytes) to
532 * generate two streams of pseudo-random bits. These two bit streams
533 * are then combined by simply adding with carry to generate a final
534 * sequence of pseudo-random bits which is stored in the buffer that
535 * 'output' points to the end of - len is the size of this buffer.
537 * The first LFSR is of degree 25, and has a polynomial of:
538 * x^13 + x^5 + x^4 + x^1 + 1
540 * The second LSFR is of degree 17, and has a (primitive) polynomial of:
543 * I don't know if these polynomials are primitive modulo 2, and thus
544 * represent maximal-period LFSR's.
547 * Note that we take the output of each LFSR from the new shifted in
548 * bit, not the old shifted out bit. Thus for ease of use the LFSR's
549 * are implemented in bit reversed order.
553 /* In order to ensure that the LFSR works we need to ensure that the
554 * initial values are non-zero. Thus when we initialise them from
555 * the seed, we ensure that a bit is set.
557 i_lfsr0 = ( pi_tmp1[0] << 17 ) | ( pi_tmp1[1] << 9 ) |
558 (( pi_tmp1[2] & ~7 ) << 1 ) | 8 | ( pi_tmp1[2] & 7 );
559 i_lfsr1 = ( pi_tmp1[3] << 9 ) | 0x100 | pi_tmp1[4];
561 i_index = sizeof(pi_bits);
566 for( i_bit = 0, i_val = 0 ; i_bit < 8 ; ++i_bit )
569 i_lfsr0_o = ( ( i_lfsr0 >> 24 ) ^ ( i_lfsr0 >> 21 ) ^
570 ( i_lfsr0 >> 20 ) ^ ( i_lfsr0 >> 12 ) ) & 1;
571 i_lfsr0 = ( i_lfsr0 << 1 ) | i_lfsr0_o;
573 i_lfsr1_o = ( ( i_lfsr1 >> 16 ) ^ ( i_lfsr1 >> 2 ) ) & 1;
574 i_lfsr1 = ( i_lfsr1 << 1 ) | i_lfsr1_o;
576 #define BIT0(x) ((x) & 1)
577 #define BIT1(x) (((x) >> 1) & 1)
579 i_combined = !i_lfsr1_o + i_carry + !i_lfsr0_o;
581 i_carry = ( i_combined >> 1 ) & 1;
582 i_val |= ( i_combined & 1 ) << i_bit;
585 pi_bits[--i_index] = i_val;
586 } while( i_index > 0 );
588 /* This term is used throughout the following to
589 * select one of 32 different variations on the
592 i_cse = pi_varients[i_css_varient] ^ pi_crypt_tab2[i_css_varient];
594 /* Now the actual blocks doing the encryption. Each
595 * of these works on 40 bits at a time and are quite
599 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_scratch[i] )
601 i_index = pi_bits[25 + i] ^ pi_scratch[i];
602 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
604 pi_tmp1[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
606 pi_tmp1[4] ^= pi_tmp1[0];
608 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
610 i_index = pi_bits[20 + i] ^ pi_tmp1[i];
611 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
613 pi_tmp2[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
615 pi_tmp2[4] ^= pi_tmp2[0];
617 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp2[i] )
619 i_index = pi_bits[15 + i] ^ pi_tmp2[i];
620 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
621 i_index = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
623 pi_tmp1[i] = pi_crypt_tab0[i_index] ^ pi_crypt_tab2[i_index];
625 pi_tmp1[4] ^= pi_tmp1[0];
627 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
629 i_index = pi_bits[10 + i] ^ pi_tmp1[i];
630 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
632 i_index = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
634 pi_tmp2[i] = pi_crypt_tab0[i_index] ^ pi_crypt_tab2[i_index];
636 pi_tmp2[4] ^= pi_tmp2[0];
638 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp2[i] )
640 i_index = pi_bits[5 + i] ^ pi_tmp2[i];
641 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
643 pi_tmp1[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
645 pi_tmp1[4] ^= pi_tmp1[0];
647 for(i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
649 i_index = pi_bits[i] ^ pi_tmp1[i];
650 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
652 pi_key[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
658 /*****************************************************************************
659 * CSSCracker : title key decryption by cracking
661 * This function is called by CSSGetKeys to find a key
662 *****************************************************************************/
663 static int CSSCracker( int i_start,
664 unsigned char * p_crypted,
665 unsigned char * p_decrypted,
666 dvd_key_t * p_sector_key,
669 unsigned char pi_buffer[10];
670 unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
672 unsigned int i_candidate;
677 for( i = 0 ; i < 10 ; i++ )
679 pi_buffer[i] = pi_css_tab1[p_crypted[i]] ^ p_decrypted[i];
682 for( i_try = i_start ; i_try < 0x10000 ; i_try++ )
684 i_t1 = i_try >> 8 | 0x100;
686 i_t3 = 0; /* not needed */
689 /* iterate cipher 4 times to reconstruct LFSR2 */
690 for( i = 0 ; i < 4 ; i++ )
692 /* advance LFSR1 normaly */
693 i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
695 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
696 i_t4 = pi_css_tab5[i_t4];
697 /* deduce i_t6 & i_t5 */
701 i_t6 = ( i_t6 + 0xff ) & 0x0ff;
709 i_t6 = pi_css_tab4[ i_t6 ];
710 /* feed / advance i_t3 / i_t5 */
711 i_t3 = ( i_t3 << 8 ) | i_t6;
717 /* iterate 6 more times to validate candidate key */
718 for( ; i < 10 ; i++ )
720 i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
722 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
723 i_t4 = pi_css_tab5[i_t4];
724 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
725 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
726 i_t3 = ( i_t3 << 8 ) | i_t6;
727 i_t6 = pi_css_tab4[i_t6];
729 if( ( i_t5 & 0xff ) != pi_buffer[i] )
739 /* Do 4 backwards steps of iterating t3 to deduce initial state */
741 for( i = 0 ; i < 4 ; i++ )
744 i_t3 = ( i_t3 >> 8 );
745 /* easy to code, and fast enough bruteforce
746 * search for byte shifted in */
747 for( j = 0 ; j < 256 ; j++ )
749 i_t3 = ( i_t3 & 0x1ffff) | ( j << 17 );
750 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
751 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
759 i_t4 = ( i_t3 >> 1 ) - 4;
760 for( i_t5 = 0 ; i_t5 < 8; i_t5++ )
762 if( ( ( i_t4 + i_t5 ) * 2 + 8 - ( (i_t4 + i_t5 ) & 7 ) )
765 (*p_key)[0] = i_try>>8;
766 (*p_key)[1] = i_try & 0xFF;
767 (*p_key)[2] = ( ( i_t4 + i_t5 ) >> 0) & 0xFF;
768 (*p_key)[3] = ( ( i_t4 + i_t5 ) >> 8) & 0xFF;
769 (*p_key)[4] = ( ( i_t4 + i_t5 ) >> 16) & 0xFF;
778 (*p_key)[0] ^= (*p_sector_key)[0];
779 (*p_key)[1] ^= (*p_sector_key)[1];
780 (*p_key)[2] ^= (*p_sector_key)[2];
781 (*p_key)[3] ^= (*p_sector_key)[3];
782 (*p_key)[4] ^= (*p_sector_key)[4];
789 * Authentication and keys
792 /*****************************************************************************
793 * CSSTest : check if the disc is encrypted or not
794 *****************************************************************************/
795 int CSSTest( int i_fd )
799 dvd.type = DVD_STRUCT_COPYRIGHT;
800 dvd.copyright.layer_num = 0;
802 if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
804 intf_ErrMsg( "DVD ioctl error" );
808 return dvd.copyright.cpst;
811 /*****************************************************************************
812 * CSSInit : CSS Structure initialisation and DVD authentication.
813 * It simulates the mutual authentication between logical unit and host.
815 * Since we don't need the disc key to find the title key, we just run the
816 * basic unavoidable commands to authenticate device and disc.
817 *****************************************************************************/
819 css_t CSSInit( int i_fd )
821 /* structures defined in cdrom.h or dvdio.h */
822 dvd_authinfo auth_info;
832 memset( &auth_info, 0, sizeof(auth_info) );
834 /* Test authentication success */
835 switch( CSSGetASF( i_fd ) )
842 intf_WarnMsg( 3, "CSS: Authenticating" );
845 /* Init sequence, request AGID */
846 for( i = 1; i < 4 ; ++i )
848 intf_WarnMsg( 3, "CSS: Request AGID %d", i );
849 auth_info.type = DVD_LU_SEND_AGID;
850 auth_info.lsa.agid = 0;
851 i_error = dvd_ioctl( i_fd, DVD_AUTH, &auth_info );
854 /* No error during ioctl: we know if device
855 * is authenticated */
859 intf_ErrMsg( "CSS: AGID N/A, invalidating" );
860 auth_info.type = DVD_INVALIDATE_AGID;
861 auth_info.lsa.agid = 0;
862 dvd_ioctl( i_fd, DVD_AUTH, &auth_info );
865 /* Unable to authenticate without AGID */
869 intf_ErrMsg( "CSS: Cannot get AGID" );
873 for( i = 0 ; i < 10; ++i )
875 css.disc.pi_challenge[i] = i;
878 /* Send AGID to host */
879 auth_info.type = DVD_HOST_SEND_CHALLENGE;
881 /* Get challenge from host */
882 for( i = 0 ; i < 10 ; ++i )
884 auth_info.hsc.chal[9-i] = css.disc.pi_challenge[i];
886 /* Returning data, let LU change state */
887 css.i_agid = auth_info.lsa.agid;
889 /* Send challenge to LU */
890 if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info )<0 )
892 intf_ErrMsg( "CSS: Send challenge to LU failed ");
897 /* Get key1 from LU */
898 if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0)
900 intf_ErrMsg( "CSS: Get key1 from LU failed ");
905 /* Send key1 to host */
906 for( i = 0 ; i < KEY_SIZE ; i++ )
908 css.disc.pi_key1[i] = auth_info.lsk.key[4-i];
911 for( i = 0 ; i < 32 ; ++i )
913 CSSCryptKey( 0, i, css.disc.pi_challenge,
914 css.disc.pi_key_check );
916 if( memcmp( css.disc.pi_key_check,
917 css.disc.pi_key1, KEY_SIZE ) == 0 )
919 intf_WarnMsg( 3, "CSS: Drive Authentic - using varient %d", i);
920 css.disc.i_varient = i;
921 auth_info.type = DVD_LU_SEND_CHALLENGE;
928 intf_ErrMsg( "Drive would not Authenticate" );
929 auth_info.type = DVD_AUTH_FAILURE;
934 /* Get challenge from LU */
935 if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
937 intf_ErrMsg( "CSS: Get challenge from LU failed ");
942 /* Send challenge to host */
943 for( i = 0 ; i < 10 ; ++i )
945 css.disc.pi_challenge[i] = auth_info.hsc.chal[9-i];
948 CSSCryptKey( 1, css.disc.i_varient, css.disc.pi_challenge,
950 auth_info.type = DVD_HOST_SEND_KEY2;
952 /* Get key2 from host */
953 for( i = 0 ; i < KEY_SIZE ; ++i )
955 auth_info.hsk.key[4-i] = css.disc.pi_key2[i];
957 /* Returning data, let LU change state */
959 /* Send key2 to LU */
960 if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
962 intf_ErrMsg( "CSS: Send key2 to LU failed (expected)" );
966 if( auth_info.type == DVD_AUTH_ESTABLISHED )
968 intf_WarnMsg( 3, "CSS: Authentication established");
970 else if( auth_info.type == DVD_AUTH_FAILURE )
973 intf_ErrMsg("CSS: DVD authentication failed");
976 memcpy( css.disc.pi_challenge, css.disc.pi_key1, KEY_SIZE );
977 memcpy( css.disc.pi_challenge+KEY_SIZE, css.disc.pi_key2, KEY_SIZE );
978 CSSCryptKey( 2, css.disc.i_varient,
979 css.disc.pi_challenge,
980 css.disc.pi_key_check );
982 intf_WarnMsg( 1, "CSS: Received Session Key" );
990 /* Test authentication success */
991 switch( CSSGetASF( i_fd ) )
998 intf_WarnMsg( 3, "CSS: Getting disc key" );
1001 /* Get encrypted disc key */
1002 dvd.type = DVD_STRUCT_DISCKEY;
1003 dvd.disckey.agid = css.i_agid;
1004 memset( dvd.disckey.value, 0, 2048 );
1006 if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
1008 intf_ErrMsg( "CSS: Could not read Disc Key" );
1013 /* Unencrypt disc key using bus key */
1014 for( i = 0 ; i < sizeof(dvd.disckey.value) ; i++ )
1016 dvd.disckey.value[i] ^= css.disc.pi_key_check[4 - (i % KEY_SIZE)];
1018 memcpy( css.disc.pi_key_check, dvd.disckey.value, 2048 );
1020 /* Test authentication success */
1021 switch( CSSGetASF( i_fd ) )
1033 /*****************************************************************************
1034 * CSSGetKey : get title key.
1035 * The DVD should have been opened and authenticated before.
1036 *****************************************************************************/
1037 int CSSGetKey( css_t * p_css )
1040 * Title key cracking method from Ethan Hawke,
1041 * with Frank A. Stevenson algorithm.
1042 * Does not use any player key table and ioctls.
1046 title_key_t p_title_key[10];
1048 boolean_t b_encrypted;
1049 boolean_t b_stop_scanning;
1054 int i_registered_keys;
1055 int i_total_keys_found;
1059 memset( p_title_key, 0, 10 );
1060 memset( &pi_key, 0, 10 );
1062 b_stop_scanning = 0;
1063 i_registered_keys = 0 ;
1064 i_total_keys_found = 0 ;
1067 /* Position of the title on the disc */
1068 i_title = p_css->i_title;
1069 i_pos = p_css->i_title_pos;
1071 //fprintf( stderr, "CSS %d start pos: %lld\n", i_title, i_pos );
1074 i_pos = lseek( p_css->i_fd, i_pos, SEEK_SET );
1075 i_bytes_read = read( p_css->i_fd, pi_buf, 0x800 );
1077 /* PES_scrambling_control */
1078 if( pi_buf[0x14] & 0x30 )
1084 for( i = 2 ; i < 0x30 ; i++ )
1086 for( j = i ; ( j < 0x80 ) &&
1087 ( pi_buf[0x7F - (j%i)] == pi_buf[0x7F-j] ) ; j++ );
1089 if( ( j > i_best_plen ) && ( j > i ) )
1097 if( ( i_best_plen > 20 ) && ( i_best_plen / i_best_p >= 2) )
1099 i = CSSCracker( 0, &pi_buf[0x80],
1100 &pi_buf[0x80 - ( i_best_plen / i_best_p) *i_best_p],
1101 (dvd_key_t*)&pi_buf[0x54],
1106 for( j=0 ; j<i_registered_keys ; j++ )
1108 if( memcmp( &(p_title_key[j].pi_key),
1109 &pi_key, sizeof(dvd_key_t) ) == 0 )
1111 p_title_key[j].i_occ++;
1112 i_total_keys_found++;
1119 memcpy( &(p_title_key[i_registered_keys].pi_key),
1120 &pi_key, sizeof(dvd_key_t) );
1121 p_title_key[i_registered_keys++].i_occ = 1;
1122 i_total_keys_found++;
1124 i = CSSCracker( i, &pi_buf[0x80],
1125 &pi_buf[0x80 - ( i_best_plen / i_best_p) *i_best_p],
1126 (dvd_key_t*)&pi_buf[0x54], &pi_key);
1129 /* Stop search if we find one occurance of the key
1130 * I have never found a DVD for which it is not enough
1131 * but we should take care of that */
1132 if( i_registered_keys == 1 && p_title_key[0].i_occ >= 1 )
1134 b_stop_scanning = 1;
1139 i_pos += i_bytes_read;
1140 } while( i_bytes_read == 0x800 && !b_stop_scanning);
1142 if( b_stop_scanning)
1145 "CSS: Found enough occurancies of the same key." );
1150 intf_WarnMsg( 3, "CSS: This file was _NOT_ encrypted!");
1154 if( b_encrypted && i_registered_keys == 0 )
1156 intf_ErrMsg( "CSS: Unable to determine keys from file.");
1160 for( i = 0 ; i < i_registered_keys - 1 ; i++ )
1162 for( j = i + 1 ; j < i_registered_keys ; j++ )
1164 if( p_title_key[j].i_occ > p_title_key[i].i_occ )
1166 memcpy( &pi_key, &(p_title_key[j].pi_key), sizeof(dvd_key_t) );
1167 k = p_title_key[j].i_occ;
1169 memcpy( &(p_title_key[j].pi_key),
1170 &(p_title_key[i].pi_key), sizeof(dvd_key_t) );
1171 p_title_key[j].i_occ = p_title_key[i].i_occ;
1173 memcpy( &(p_title_key[i].pi_key),&pi_key, sizeof(dvd_key_t) );
1174 p_title_key[i].i_occ = k;
1180 intf_WarnMsg( 1, " Key(s) & key probability\n---------------------");
1182 for( i=0 ; i<i_registered_keys ; i++ )
1185 intf_WarnMsg( 1, "%d) %02X %02X %02X %02X %02X - %3.2f%%", i,
1186 p_title_key[i].key[0], p_title_key[i].key[1],
1187 p_title_key[i].key[2], p_title_key[i].key[3],
1188 p_title_key[i].key[4],
1189 p_title_key[i].i_occ * 100.0 / i_total_keys_found );
1191 if( p_title_key[i_highest].i_occ * 100.0 / i_total_keys_found
1192 <= p_title_key[i].i_occ*100.0 / i_total_keys_found )
1199 /* The "find the key with the highest probability" code
1200 * is untested, as I haven't been able to find a VOB that
1201 * produces multiple keys (RT)
1203 intf_WarnMsg( 3, "CSS: Title %d key: %02X %02X %02X %02X %02X",
1205 p_title_key[i_highest].pi_key[0],
1206 p_title_key[i_highest].pi_key[1],
1207 p_title_key[i_highest].pi_key[2],
1208 p_title_key[i_highest].pi_key[3],
1209 p_title_key[i_highest].pi_key[4] );
1211 memcpy( p_css->pi_title_key,
1212 p_title_key[i_highest].pi_key, KEY_SIZE );
1217 /*****************************************************************************
1218 * CSSDescrambleSector
1220 * sec : sector to descramble
1221 * key : title key for this sector
1222 *****************************************************************************/
1223 int CSSDescrambleSector( dvd_key_t pi_key, u8* pi_sec )
1225 unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
1226 u8* pi_end = pi_sec + 0x800;
1228 /* PES_scrambling_control */
1229 if( pi_sec[0x14] & 0x30)
1231 i_t1 = ((pi_key)[0] ^ pi_sec[0x54]) | 0x100;
1232 i_t2 = (pi_key)[1] ^ pi_sec[0x55];
1233 i_t3 = (((pi_key)[2]) | ((pi_key)[3] << 8) |
1234 ((pi_key)[4] << 16)) ^ ((pi_sec[0x56]) |
1235 (pi_sec[0x57] << 8) | (pi_sec[0x58] << 16));
1237 i_t3 = i_t3 * 2 + 8 - i_t4;
1241 while( pi_sec != pi_end )
1243 i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
1245 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
1246 i_t4 = pi_css_tab5[i_t4];
1247 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
1248 i_t3 ) >> 8 ) ^ i_t3 ) >> 5) & 0xff;
1249 i_t3 = (i_t3 << 8 ) | i_t6;
1250 i_t6 = pi_css_tab4[i_t6];
1251 i_t5 += i_t6 + i_t4;
1252 *pi_sec++ = pi_css_tab1[*pi_sec] ^( i_t5 & 0xff );