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.10 2001/02/18 01:42:04 stef 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 )
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>
58 #include "input_dvd.h"
60 /*****************************************************************************
62 *****************************************************************************/
63 static u8 pi_css_tab1[256]=
64 { 0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76,
65 0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b,
66 0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96,
67 0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b,
68 0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12,
69 0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f,
70 0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90,
71 0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91,
72 0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74,
73 0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75,
74 0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94,
75 0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95,
76 0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10,
77 0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11,
78 0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92,
79 0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f,
80 0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16,
81 0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b,
82 0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6,
83 0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb,
84 0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72,
85 0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f,
86 0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0,
87 0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1,
88 0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14,
89 0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15,
90 0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4,
91 0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5,
92 0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70,
93 0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71,
94 0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2,
95 0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff
98 static u8 pi_css_tab2[256]=
99 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
100 0x09, 0x08, 0x0b, 0x0a, 0x0d, 0x0c, 0x0f, 0x0e,
101 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15,
102 0x1b, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x1d, 0x1c,
103 0x24, 0x25, 0x26, 0x27, 0x20, 0x21, 0x22, 0x23,
104 0x2d, 0x2c, 0x2f, 0x2e, 0x29, 0x28, 0x2b, 0x2a,
105 0x36, 0x37, 0x34, 0x35, 0x32, 0x33, 0x30, 0x31,
106 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
107 0x49, 0x48, 0x4b, 0x4a, 0x4d, 0x4c, 0x4f, 0x4e,
108 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
109 0x5b, 0x5a, 0x59, 0x58, 0x5f, 0x5e, 0x5d, 0x5c,
110 0x52, 0x53, 0x50, 0x51, 0x56, 0x57, 0x54, 0x55,
111 0x6d, 0x6c, 0x6f, 0x6e, 0x69, 0x68, 0x6b, 0x6a,
112 0x64, 0x65, 0x66, 0x67, 0x60, 0x61, 0x62, 0x63,
113 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
114 0x76, 0x77, 0x74, 0x75, 0x72, 0x73, 0x70, 0x71,
115 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95,
116 0x9b, 0x9a, 0x99, 0x98, 0x9f, 0x9e, 0x9d, 0x9c,
117 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
118 0x89, 0x88, 0x8b, 0x8a, 0x8d, 0x8c, 0x8f, 0x8e,
119 0xb6, 0xb7, 0xb4, 0xb5, 0xb2, 0xb3, 0xb0, 0xb1,
120 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
121 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3,
122 0xad, 0xac, 0xaf, 0xae, 0xa9, 0xa8, 0xab, 0xaa,
123 0xdb, 0xda, 0xd9, 0xd8, 0xdf, 0xde, 0xdd, 0xdc,
124 0xd2, 0xd3, 0xd0, 0xd1, 0xd6, 0xd7, 0xd4, 0xd5,
125 0xc9, 0xc8, 0xcb, 0xca, 0xcd, 0xcc, 0xcf, 0xce,
126 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
127 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
128 0xf6, 0xf7, 0xf4, 0xf5, 0xf2, 0xf3, 0xf0, 0xf1,
129 0xed, 0xec, 0xef, 0xee, 0xe9, 0xe8, 0xeb, 0xea,
130 0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3
133 static u8 pi_css_tab3[512]=
134 { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
135 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
136 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
137 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
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
200 static u8 pi_css_tab4[256]=
201 { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
202 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
203 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
204 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
205 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
206 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
207 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
208 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
209 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
210 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
211 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
212 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
213 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
214 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
215 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
216 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
217 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
218 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
219 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
220 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
221 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
222 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
223 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
224 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
225 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
226 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
227 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
228 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
229 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
230 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
231 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
232 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
235 static u8 pi_css_tab5[256]=
236 { 0xff, 0x7f, 0xbf, 0x3f, 0xdf, 0x5f, 0x9f, 0x1f,
237 0xef, 0x6f, 0xaf, 0x2f, 0xcf, 0x4f, 0x8f, 0x0f,
238 0xf7, 0x77, 0xb7, 0x37, 0xd7, 0x57, 0x97, 0x17,
239 0xe7, 0x67, 0xa7, 0x27, 0xc7, 0x47, 0x87, 0x07,
240 0xfb, 0x7b, 0xbb, 0x3b, 0xdb, 0x5b, 0x9b, 0x1b,
241 0xeb, 0x6b, 0xab, 0x2b, 0xcb, 0x4b, 0x8b, 0x0b,
242 0xf3, 0x73, 0xb3, 0x33, 0xd3, 0x53, 0x93, 0x13,
243 0xe3, 0x63, 0xa3, 0x23, 0xc3, 0x43, 0x83, 0x03,
244 0xfd, 0x7d, 0xbd, 0x3d, 0xdd, 0x5d, 0x9d, 0x1d,
245 0xed, 0x6d, 0xad, 0x2d, 0xcd, 0x4d, 0x8d, 0x0d,
246 0xf5, 0x75, 0xb5, 0x35, 0xd5, 0x55, 0x95, 0x15,
247 0xe5, 0x65, 0xa5, 0x25, 0xc5, 0x45, 0x85, 0x05,
248 0xf9, 0x79, 0xb9, 0x39, 0xd9, 0x59, 0x99, 0x19,
249 0xe9, 0x69, 0xa9, 0x29, 0xc9, 0x49, 0x89, 0x09,
250 0xf1, 0x71, 0xb1, 0x31, 0xd1, 0x51, 0x91, 0x11,
251 0xe1, 0x61, 0xa1, 0x21, 0xc1, 0x41, 0x81, 0x01,
252 0xfe, 0x7e, 0xbe, 0x3e, 0xde, 0x5e, 0x9e, 0x1e,
253 0xee, 0x6e, 0xae, 0x2e, 0xce, 0x4e, 0x8e, 0x0e,
254 0xf6, 0x76, 0xb6, 0x36, 0xd6, 0x56, 0x96, 0x16,
255 0xe6, 0x66, 0xa6, 0x26, 0xc6, 0x46, 0x86, 0x06,
256 0xfa, 0x7a, 0xba, 0x3a, 0xda, 0x5a, 0x9a, 0x1a,
257 0xea, 0x6a, 0xaa, 0x2a, 0xca, 0x4a, 0x8a, 0x0a,
258 0xf2, 0x72, 0xb2, 0x32, 0xd2, 0x52, 0x92, 0x12,
259 0xe2, 0x62, 0xa2, 0x22, 0xc2, 0x42, 0x82, 0x02,
260 0xfc, 0x7c, 0xbc, 0x3c, 0xdc, 0x5c, 0x9c, 0x1c,
261 0xec, 0x6c, 0xac, 0x2c, 0xcc, 0x4c, 0x8c, 0x0c,
262 0xf4, 0x74, 0xb4, 0x34, 0xd4, 0x54, 0x94, 0x14,
263 0xe4, 0x64, 0xa4, 0x24, 0xc4, 0x44, 0x84, 0x04,
264 0xf8, 0x78, 0xb8, 0x38, 0xd8, 0x58, 0x98, 0x18,
265 0xe8, 0x68, 0xa8, 0x28, 0xc8, 0x48, 0x88, 0x08,
266 0xf0, 0x70, 0xb0, 0x30, 0xd0, 0x50, 0x90, 0x10,
267 0xe0, 0x60, 0xa0, 0x20, 0xc0, 0x40, 0x80, 0x00
270 static u8 pi_crypt_tab0[256] = {
271 0xB7, 0xF4, 0x82, 0x57, 0xDA, 0x4D, 0xDB, 0xE2,
272 0x2F, 0x52, 0x1A, 0xA8, 0x68, 0x5A, 0x8A, 0xFF,
273 0xFB, 0x0E, 0x6D, 0x35, 0xF7, 0x5C, 0x76, 0x12,
274 0xCE, 0x25, 0x79, 0x29, 0x39, 0x62, 0x08, 0x24,
275 0xA5, 0x85, 0x7B, 0x56, 0x01, 0x23, 0x68, 0xCF,
276 0x0A, 0xE2, 0x5A, 0xED, 0x3D, 0x59, 0xB0, 0xA9,
277 0xB0, 0x2C, 0xF2, 0xB8, 0xEF, 0x32, 0xA9, 0x40,
278 0x80, 0x71, 0xAF, 0x1E, 0xDE, 0x8F, 0x58, 0x88,
279 0xB8, 0x3A, 0xD0, 0xFC, 0xC4, 0x1E, 0xB5, 0xA0,
280 0xBB, 0x3B, 0x0F, 0x01, 0x7E, 0x1F, 0x9F, 0xD9,
281 0xAA, 0xB8, 0x3D, 0x9D, 0x74, 0x1E, 0x25, 0xDB,
282 0x37, 0x56, 0x8F, 0x16, 0xBA, 0x49, 0x2B, 0xAC,
283 0xD0, 0xBD, 0x95, 0x20, 0xBE, 0x7A, 0x28, 0xD0,
284 0x51, 0x64, 0x63, 0x1C, 0x7F, 0x66, 0x10, 0xBB,
285 0xC4, 0x56, 0x1A, 0x04, 0x6E, 0x0A, 0xEC, 0x9C,
286 0xD6, 0xE8, 0x9A, 0x7A, 0xCF, 0x8C, 0xDB, 0xB1,
287 0xEF, 0x71, 0xDE, 0x31, 0xFF, 0x54, 0x3E, 0x5E,
288 0x07, 0x69, 0x96, 0xB0, 0xCF, 0xDD, 0x9E, 0x47,
289 0xC7, 0x96, 0x8F, 0xE4, 0x2B, 0x59, 0xC6, 0xEE,
290 0xB9, 0x86, 0x9A, 0x64, 0x84, 0x72, 0xE2, 0x5B,
291 0xA2, 0x96, 0x58, 0x99, 0x50, 0x03, 0xF5, 0x38,
292 0x4D, 0x02, 0x7D, 0xE7, 0x7D, 0x75, 0xA7, 0xB8,
293 0x67, 0x87, 0x84, 0x3F, 0x1D, 0x11, 0xE5, 0xFC,
294 0x1E, 0xD3, 0x83, 0x16, 0xA5, 0x29, 0xF6, 0xC7,
295 0x15, 0x61, 0x29, 0x1A, 0x43, 0x4F, 0x9B, 0xAF,
296 0xC5, 0x87, 0x34, 0x6C, 0x0F, 0x3B, 0xA8, 0x1D,
297 0x45, 0x58, 0x25, 0xDC, 0xA8, 0xA3, 0x3B, 0xD1,
298 0x79, 0x1B, 0x48, 0xF2, 0xE9, 0x93, 0x1F, 0xFC,
299 0xDB, 0x2A, 0x90, 0xA9, 0x8A, 0x3D, 0x39, 0x18,
300 0xA3, 0x8E, 0x58, 0x6C, 0xE0, 0x12, 0xBB, 0x25,
301 0xCD, 0x71, 0x22, 0xA2, 0x64, 0xC6, 0xE7, 0xFB,
302 0xAD, 0x94, 0x77, 0x04, 0x9A, 0x39, 0xCF, 0x7C};
304 static u8 pi_crypt_tab1[256] = {
305 0x8C, 0x47, 0xB0, 0xE1, 0xEB, 0xFC, 0xEB, 0x56,
306 0x10, 0xE5, 0x2C, 0x1A, 0x5D, 0xEF, 0xBE, 0x4F,
307 0x08, 0x75, 0x97, 0x4B, 0x0E, 0x25, 0x8E, 0x6E,
308 0x39, 0x5A, 0x87, 0x53, 0xC4, 0x1F, 0xF4, 0x5C,
309 0x4E, 0xE6, 0x99, 0x30, 0xE0, 0x42, 0x88, 0xAB,
310 0xE5, 0x85, 0xBC, 0x8F, 0xD8, 0x3C, 0x54, 0xC9,
311 0x53, 0x47, 0x18, 0xD6, 0x06, 0x5B, 0x41, 0x2C,
312 0x67, 0x1E, 0x41, 0x74, 0x33, 0xE2, 0xB4, 0xE0,
313 0x23, 0x29, 0x42, 0xEA, 0x55, 0x0F, 0x25, 0xB4,
314 0x24, 0x2C, 0x99, 0x13, 0xEB, 0x0A, 0x0B, 0xC9,
315 0xF9, 0x63, 0x67, 0x43, 0x2D, 0xC7, 0x7D, 0x07,
316 0x60, 0x89, 0xD1, 0xCC, 0xE7, 0x94, 0x77, 0x74,
317 0x9B, 0x7E, 0xD7, 0xE6, 0xFF, 0xBB, 0x68, 0x14,
318 0x1E, 0xA3, 0x25, 0xDE, 0x3A, 0xA3, 0x54, 0x7B,
319 0x87, 0x9D, 0x50, 0xCA, 0x27, 0xC3, 0xA4, 0x50,
320 0x91, 0x27, 0xD4, 0xB0, 0x82, 0x41, 0x97, 0x79,
321 0x94, 0x82, 0xAC, 0xC7, 0x8E, 0xA5, 0x4E, 0xAA,
322 0x78, 0x9E, 0xE0, 0x42, 0xBA, 0x28, 0xEA, 0xB7,
323 0x74, 0xAD, 0x35, 0xDA, 0x92, 0x60, 0x7E, 0xD2,
324 0x0E, 0xB9, 0x24, 0x5E, 0x39, 0x4F, 0x5E, 0x63,
325 0x09, 0xB5, 0xFA, 0xBF, 0xF1, 0x22, 0x55, 0x1C,
326 0xE2, 0x25, 0xDB, 0xC5, 0xD8, 0x50, 0x03, 0x98,
327 0xC4, 0xAC, 0x2E, 0x11, 0xB4, 0x38, 0x4D, 0xD0,
328 0xB9, 0xFC, 0x2D, 0x3C, 0x08, 0x04, 0x5A, 0xEF,
329 0xCE, 0x32, 0xFB, 0x4C, 0x92, 0x1E, 0x4B, 0xFB,
330 0x1A, 0xD0, 0xE2, 0x3E, 0xDA, 0x6E, 0x7C, 0x4D,
331 0x56, 0xC3, 0x3F, 0x42, 0xB1, 0x3A, 0x23, 0x4D,
332 0x6E, 0x84, 0x56, 0x68, 0xF4, 0x0E, 0x03, 0x64,
333 0xD0, 0xA9, 0x92, 0x2F, 0x8B, 0xBC, 0x39, 0x9C,
334 0xAC, 0x09, 0x5E, 0xEE, 0xE5, 0x97, 0xBF, 0xA5,
335 0xCE, 0xFA, 0x28, 0x2C, 0x6D, 0x4F, 0xEF, 0x77,
336 0xAA, 0x1B, 0x79, 0x8E, 0x97, 0xB4, 0xC3, 0xF4};
338 static u8 pi_crypt_tab2[256] = {
339 0xB7, 0x75, 0x81, 0xD5, 0xDC, 0xCA, 0xDE, 0x66,
340 0x23, 0xDF, 0x15, 0x26, 0x62, 0xD1, 0x83, 0x77,
341 0xE3, 0x97, 0x76, 0xAF, 0xE9, 0xC3, 0x6B, 0x8E,
342 0xDA, 0xB0, 0x6E, 0xBF, 0x2B, 0xF1, 0x19, 0xB4,
343 0x95, 0x34, 0x48, 0xE4, 0x37, 0x94, 0x5D, 0x7B,
344 0x36, 0x5F, 0x65, 0x53, 0x07, 0xE2, 0x89, 0x11,
345 0x98, 0x85, 0xD9, 0x12, 0xC1, 0x9D, 0x84, 0xEC,
346 0xA4, 0xD4, 0x88, 0xB8, 0xFC, 0x2C, 0x79, 0x28,
347 0xD8, 0xDB, 0xB3, 0x1E, 0xA2, 0xF9, 0xD0, 0x44,
348 0xD7, 0xD6, 0x60, 0xEF, 0x14, 0xF4, 0xF6, 0x31,
349 0xD2, 0x41, 0x46, 0x67, 0x0A, 0xE1, 0x58, 0x27,
350 0x43, 0xA3, 0xF8, 0xE0, 0xC8, 0xBA, 0x5A, 0x5C,
351 0x80, 0x6C, 0xC6, 0xF2, 0xE8, 0xAD, 0x7D, 0x04,
352 0x0D, 0xB9, 0x3C, 0xC2, 0x25, 0xBD, 0x49, 0x63,
353 0x8C, 0x9F, 0x51, 0xCE, 0x20, 0xC5, 0xA1, 0x50,
354 0x92, 0x2D, 0xDD, 0xBC, 0x8D, 0x4F, 0x9A, 0x71,
355 0x2F, 0x30, 0x1D, 0x73, 0x39, 0x13, 0xFB, 0x1A,
356 0xCB, 0x24, 0x59, 0xFE, 0x05, 0x96, 0x57, 0x0F,
357 0x1F, 0xCF, 0x54, 0xBE, 0xF5, 0x06, 0x1B, 0xB2,
358 0x6D, 0xD3, 0x4D, 0x32, 0x56, 0x21, 0x33, 0x0B,
359 0x52, 0xE7, 0xAB, 0xEB, 0xA6, 0x74, 0x00, 0x4C,
360 0xB1, 0x7F, 0x82, 0x99, 0x87, 0x0E, 0x5E, 0xC0,
361 0x8F, 0xEE, 0x6F, 0x55, 0xF3, 0x7E, 0x08, 0x90,
362 0xFA, 0xB6, 0x64, 0x70, 0x47, 0x4A, 0x17, 0xA7,
363 0xB5, 0x40, 0x8A, 0x38, 0xE5, 0x68, 0x3E, 0x8B,
364 0x69, 0xAA, 0x9B, 0x42, 0xA5, 0x10, 0x01, 0x35,
365 0xFD, 0x61, 0x9E, 0xE6, 0x16, 0x9C, 0x86, 0xED,
366 0xCD, 0x2E, 0xFF, 0xC4, 0x5B, 0xA0, 0xAE, 0xCC,
367 0x4B, 0x3B, 0x03, 0xBB, 0x1C, 0x2A, 0xAC, 0x0C,
368 0x3F, 0x93, 0xC7, 0x72, 0x7A, 0x09, 0x22, 0x3D,
369 0x45, 0x78, 0xA9, 0xA8, 0xEA, 0xC9, 0x6A, 0xF7,
370 0x29, 0x91, 0xF0, 0x02, 0x18, 0x3A, 0x4E, 0x7C};
372 static u8 pi_crypt_tab3[288] = {
373 0x73, 0x51, 0x95, 0xE1, 0x12, 0xE4, 0xC0, 0x58,
374 0xEE, 0xF2, 0x08, 0x1B, 0xA9, 0xFA, 0x98, 0x4C,
375 0xA7, 0x33, 0xE2, 0x1B, 0xA7, 0x6D, 0xF5, 0x30,
376 0x97, 0x1D, 0xF3, 0x02, 0x60, 0x5A, 0x82, 0x0F,
377 0x91, 0xD0, 0x9C, 0x10, 0x39, 0x7A, 0x83, 0x85,
378 0x3B, 0xB2, 0xB8, 0xAE, 0x0C, 0x09, 0x52, 0xEA,
379 0x1C, 0xE1, 0x8D, 0x66, 0x4F, 0xF3, 0xDA, 0x92,
380 0x29, 0xB9, 0xD5, 0xC5, 0x77, 0x47, 0x22, 0x53,
381 0x14, 0xF7, 0xAF, 0x22, 0x64, 0xDF, 0xC6, 0x72,
382 0x12, 0xF3, 0x75, 0xDA, 0xD7, 0xD7, 0xE5, 0x02,
383 0x9E, 0xED, 0xDA, 0xDB, 0x4C, 0x47, 0xCE, 0x91,
384 0x06, 0x06, 0x6D, 0x55, 0x8B, 0x19, 0xC9, 0xEF,
385 0x8C, 0x80, 0x1A, 0x0E, 0xEE, 0x4B, 0xAB, 0xF2,
386 0x08, 0x5C, 0xE9, 0x37, 0x26, 0x5E, 0x9A, 0x90,
387 0x00, 0xF3, 0x0D, 0xB2, 0xA6, 0xA3, 0xF7, 0x26,
388 0x17, 0x48, 0x88, 0xC9, 0x0E, 0x2C, 0xC9, 0x02,
389 0xE7, 0x18, 0x05, 0x4B, 0xF3, 0x39, 0xE1, 0x20,
390 0x02, 0x0D, 0x40, 0xC7, 0xCA, 0xB9, 0x48, 0x30,
391 0x57, 0x67, 0xCC, 0x06, 0xBF, 0xAC, 0x81, 0x08,
392 0x24, 0x7A, 0xD4, 0x8B, 0x19, 0x8E, 0xAC, 0xB4,
393 0x5A, 0x0F, 0x73, 0x13, 0xAC, 0x9E, 0xDA, 0xB6,
394 0xB8, 0x96, 0x5B, 0x60, 0x88, 0xE1, 0x81, 0x3F,
395 0x07, 0x86, 0x37, 0x2D, 0x79, 0x14, 0x52, 0xEA,
396 0x73, 0xDF, 0x3D, 0x09, 0xC8, 0x25, 0x48, 0xD8,
397 0x75, 0x60, 0x9A, 0x08, 0x27, 0x4A, 0x2C, 0xB9,
398 0xA8, 0x8B, 0x8A, 0x73, 0x62, 0x37, 0x16, 0x02,
399 0xBD, 0xC1, 0x0E, 0x56, 0x54, 0x3E, 0x14, 0x5F,
400 0x8C, 0x8F, 0x6E, 0x75, 0x1C, 0x07, 0x39, 0x7B,
401 0x4B, 0xDB, 0xD3, 0x4B, 0x1E, 0xC8, 0x7E, 0xFE,
402 0x3E, 0x72, 0x16, 0x83, 0x7D, 0xEE, 0xF5, 0xCA,
403 0xC5, 0x18, 0xF9, 0xD8, 0x68, 0xAB, 0x38, 0x85,
404 0xA8, 0xF0, 0xA1, 0x73, 0x9F, 0x5D, 0x19, 0x0B,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x33, 0x72, 0x39, 0x25, 0x67, 0x26, 0x6D, 0x71,
407 0x36, 0x77, 0x3C, 0x20, 0x62, 0x23, 0x68, 0x74,
408 0xC3, 0x82, 0xC9, 0x15, 0x57, 0x16, 0x5D, 0x81};
413 /*****************************************************************************
414 * CSSGetASF : Get Authentification success flag
418 * 0 if the device needs to be authenticated,
420 *****************************************************************************/
421 static int CSSGetASF( int i_fd )
423 dvd_authinfo auth_info;
425 auth_info.type = DVD_LU_SEND_ASF;
426 auth_info.lsasf.asf = 0;
428 for( auth_info.lsasf.agid = 0 ; auth_info.lsasf.agid < 4 ;
429 auth_info.lsasf.agid++ )
431 if( !( ioctl( i_fd, DVD_AUTH, &auth_info ) ) )
433 intf_WarnMsg( 3, "CSS: %sAuthenticated",
434 ( auth_info.lsasf.asf ) ? "" : "not " );
435 return auth_info.lsasf.asf;
439 /* The ioctl process has failed */
440 intf_ErrMsg( "CSS: GetASF Fatal Error" );
444 /*****************************************************************************
445 * CSSCryptKey : shuffles bits and unencrypt keys.
446 * Used during authentication and disc key negociation in CSSInit.
448 * i_key_type : 0->key1, 1->key2, 2->buskey.
449 * i_varient : between 0 and 31.
450 *****************************************************************************/
451 static void CSSCryptKey( int i_key_type, int i_varient,
452 u8 const * pi_challenge, u8* pi_key )
454 /* Permutation table for challenge */
455 u8 ppi_perm_challenge[3][10] =
456 { { 1, 3, 0, 7, 5, 2, 9, 6, 4, 8 },
457 { 6, 1, 9, 3, 8, 5, 7, 4, 0, 2 },
458 { 4, 0, 3, 5, 7, 2, 8, 6, 1, 9 } };
460 /* Permutation table for varient table for key2 and buskey */
461 u8 ppi_perm_varient[2][32] =
462 { { 0x0a, 0x08, 0x0e, 0x0c, 0x0b, 0x09, 0x0f, 0x0d,
463 0x1a, 0x18, 0x1e, 0x1c, 0x1b, 0x19, 0x1f, 0x1d,
464 0x02, 0x00, 0x06, 0x04, 0x03, 0x01, 0x07, 0x05,
465 0x12, 0x10, 0x16, 0x14, 0x13, 0x11, 0x17, 0x15 },
466 { 0x12, 0x1a, 0x16, 0x1e, 0x02, 0x0a, 0x06, 0x0e,
467 0x10, 0x18, 0x14, 0x1c, 0x00, 0x08, 0x04, 0x0c,
468 0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f,
469 0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d } };
472 { 0xB7, 0x74, 0x85, 0xD0, 0xCC, 0xDB, 0xCA, 0x73,
473 0x03, 0xFE, 0x31, 0x03, 0x52, 0xE0, 0xB7, 0x42,
474 0x63, 0x16, 0xF2, 0x2A, 0x79, 0x52, 0xFF, 0x1B,
475 0x7A, 0x11, 0xCA, 0x1A, 0x9B, 0x40, 0xAD, 0x01 };
477 /* The "secret" key */
478 u8 pi_secret[5] = { 0x55, 0xD6, 0xC4, 0xC5, 0x28 };
484 u8 i_lfsr0_o; /* 1 bit used */
485 u8 i_lfsr1_o; /* 1 bit used */
498 for (i = 9; i >= 0; --i)
499 pi_scratch[i] = pi_challenge[ppi_perm_challenge[i_key_type][i]];
501 i_css_varient = ( i_key_type == 0 ) ? i_varient :
502 ppi_perm_varient[i_key_type-1][i_varient];
505 * This encryption engine implements one of 32 variations
506 * one the same theme depending upon the choice in the
507 * varient parameter (0 - 31).
509 * The algorithm itself manipulates a 40 bit input into
511 * The parameter 'input' is 80 bits. It consists of
512 * the 40 bit input value that is to be encrypted followed
513 * by a 40 bit seed value for the pseudo random number
517 /* Feed the secret into the input values such that
518 * we alter the seed to the LFSR's used above, then
519 * generate the bits to play with.
521 for( i = 5 ; --i >= 0 ; )
523 pi_tmp1[i] = pi_scratch[5 + i] ^ pi_secret[i] ^ pi_crypt_tab2[i];
527 * We use two LFSR's (seeded from some of the input data bytes) to
528 * generate two streams of pseudo-random bits. These two bit streams
529 * are then combined by simply adding with carry to generate a final
530 * sequence of pseudo-random bits which is stored in the buffer that
531 * 'output' points to the end of - len is the size of this buffer.
533 * The first LFSR is of degree 25, and has a polynomial of:
534 * x^13 + x^5 + x^4 + x^1 + 1
536 * The second LSFR is of degree 17, and has a (primitive) polynomial of:
539 * I don't know if these polynomials are primitive modulo 2, and thus
540 * represent maximal-period LFSR's.
543 * Note that we take the output of each LFSR from the new shifted in
544 * bit, not the old shifted out bit. Thus for ease of use the LFSR's
545 * are implemented in bit reversed order.
549 /* In order to ensure that the LFSR works we need to ensure that the
550 * initial values are non-zero. Thus when we initialise them from
551 * the seed, we ensure that a bit is set.
553 i_lfsr0 = ( pi_tmp1[0] << 17 ) | ( pi_tmp1[1] << 9 ) |
554 (( pi_tmp1[2] & ~7 ) << 1 ) | 8 | ( pi_tmp1[2] & 7 );
555 i_lfsr1 = ( pi_tmp1[3] << 9 ) | 0x100 | pi_tmp1[4];
557 i_index = sizeof(pi_bits);
562 for( i_bit = 0, i_val = 0 ; i_bit < 8 ; ++i_bit )
565 i_lfsr0_o = ( ( i_lfsr0 >> 24 ) ^ ( i_lfsr0 >> 21 ) ^
566 ( i_lfsr0 >> 20 ) ^ ( i_lfsr0 >> 12 ) ) & 1;
567 i_lfsr0 = ( i_lfsr0 << 1 ) | i_lfsr0_o;
569 i_lfsr1_o = ( ( i_lfsr1 >> 16 ) ^ ( i_lfsr1 >> 2 ) ) & 1;
570 i_lfsr1 = ( i_lfsr1 << 1 ) | i_lfsr1_o;
572 #define BIT0(x) ((x) & 1)
573 #define BIT1(x) (((x) >> 1) & 1)
575 i_combined = !i_lfsr1_o + i_carry + !i_lfsr0_o;
577 i_carry = ( i_combined >> 1 ) & 1;
578 i_val |= ( i_combined & 1 ) << i_bit;
581 pi_bits[--i_index] = i_val;
582 } while( i_index > 0 );
584 /* This term is used throughout the following to
585 * select one of 32 different variations on the
588 i_cse = pi_varients[i_css_varient] ^ pi_crypt_tab2[i_css_varient];
590 /* Now the actual blocks doing the encryption. Each
591 * of these works on 40 bits at a time and are quite
595 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_scratch[i] )
597 i_index = pi_bits[25 + i] ^ pi_scratch[i];
598 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
600 pi_tmp1[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
602 pi_tmp1[4] ^= pi_tmp1[0];
604 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
606 i_index = pi_bits[20 + i] ^ pi_tmp1[i];
607 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
609 pi_tmp2[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
611 pi_tmp2[4] ^= pi_tmp2[0];
613 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp2[i] )
615 i_index = pi_bits[15 + i] ^ pi_tmp2[i];
616 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
617 i_index = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
619 pi_tmp1[i] = pi_crypt_tab0[i_index] ^ pi_crypt_tab2[i_index];
621 pi_tmp1[4] ^= pi_tmp1[0];
623 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
625 i_index = pi_bits[10 + i] ^ pi_tmp1[i];
626 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
628 i_index = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
630 pi_tmp2[i] = pi_crypt_tab0[i_index] ^ pi_crypt_tab2[i_index];
632 pi_tmp2[4] ^= pi_tmp2[0];
634 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp2[i] )
636 i_index = pi_bits[5 + i] ^ pi_tmp2[i];
637 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
639 pi_tmp1[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
641 pi_tmp1[4] ^= pi_tmp1[0];
643 for(i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
645 i_index = pi_bits[i] ^ pi_tmp1[i];
646 i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
648 pi_key[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
654 /*****************************************************************************
655 * CSSCracker : title key decryption by cracking
657 * This function is called by CSSGetKeys to find a key
658 *****************************************************************************/
659 static int CSSCracker( int i_start,
660 unsigned char * p_crypted,
661 unsigned char * p_decrypted,
662 DVD_key_t * p_sector_key,
665 unsigned char pi_buffer[10];
666 unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
668 unsigned int i_candidate;
673 for( i = 0 ; i < 10 ; i++ )
675 pi_buffer[i] = pi_css_tab1[p_crypted[i]] ^ p_decrypted[i];
678 for( i_try = i_start ; i_try < 0x10000 ; i_try++ )
680 i_t1 = i_try >> 8 | 0x100;
682 i_t3 = 0; /* not needed */
685 /* iterate cipher 4 times to reconstruct LFSR2 */
686 for( i = 0 ; i < 4 ; i++ )
688 /* advance LFSR1 normaly */
689 i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
691 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
692 i_t4 = pi_css_tab5[i_t4];
693 /* deduce i_t6 & i_t5 */
697 i_t6 = ( i_t6 + 0xff ) & 0x0ff;
705 i_t6 = pi_css_tab4[ i_t6 ];
706 /* feed / advance i_t3 / i_t5 */
707 i_t3 = ( i_t3 << 8 ) | i_t6;
713 /* iterate 6 more times to validate candidate key */
714 for( ; i < 10 ; i++ )
716 i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
718 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
719 i_t4 = pi_css_tab5[i_t4];
720 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
721 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
722 i_t3 = ( i_t3 << 8 ) | i_t6;
723 i_t6 = pi_css_tab4[i_t6];
725 if( ( i_t5 & 0xff ) != pi_buffer[i] )
735 /* Do 4 backwards steps of iterating t3 to deduce initial state */
737 for( i = 0 ; i < 4 ; i++ )
740 i_t3 = ( i_t3 >> 8 );
741 /* easy to code, and fast enough bruteforce
742 * search for byte shifted in */
743 for( j = 0 ; j < 256 ; j++ )
745 i_t3 = ( i_t3 & 0x1ffff) | ( j << 17 );
746 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
747 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
755 i_t4 = ( i_t3 >> 1 ) - 4;
756 for( i_t5 = 0 ; i_t5 < 8; i_t5++ )
758 if( ( ( i_t4 + i_t5 ) * 2 + 8 - ( (i_t4 + i_t5 ) & 7 ) )
761 (*p_key)[0] = i_try>>8;
762 (*p_key)[1] = i_try & 0xFF;
763 (*p_key)[2] = ( ( i_t4 + i_t5 ) >> 0) & 0xFF;
764 (*p_key)[3] = ( ( i_t4 + i_t5 ) >> 8) & 0xFF;
765 (*p_key)[4] = ( ( i_t4 + i_t5 ) >> 16) & 0xFF;
774 (*p_key)[0] ^= (*p_sector_key)[0];
775 (*p_key)[1] ^= (*p_sector_key)[1];
776 (*p_key)[2] ^= (*p_sector_key)[2];
777 (*p_key)[3] ^= (*p_sector_key)[3];
778 (*p_key)[4] ^= (*p_sector_key)[4];
785 * Authentication and keys
788 /*****************************************************************************
789 * CSSTest : check if the disc is encrypted or not
790 *****************************************************************************/
791 int CSSTest( int i_fd )
795 dvd.type = DVD_STRUCT_COPYRIGHT;
796 dvd.copyright.layer_num = 0;
798 if( ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
800 intf_ErrMsg( "DVD ioctl error" );
804 return dvd.copyright.cpst;
807 /*****************************************************************************
808 * CSSInit : CSS Structure initialisation and DVD authentication.
809 * It simulates the mutual authentication between logical unit and host.
811 * Since we don't need the disc key to find the title key, we just run the
812 * basic unavoidable commands to authenticate device and disc.
813 *****************************************************************************/
815 css_t CSSInit( int i_fd )
817 /* structures defined in cdrom.h or dvdio.h */
818 dvd_authinfo auth_info;
828 memset( &auth_info, 0, sizeof(auth_info) );
830 /* Test authentication success */
831 switch( CSSGetASF( i_fd ) )
838 intf_WarnMsg( 3, "CSS: Authenticating" );
841 /* Init sequence, request AGID */
842 for( i = 1; i < 4 ; ++i )
844 intf_WarnMsg( 3, "CSS: Request AGID %d", i );
845 auth_info.type = DVD_LU_SEND_AGID;
846 auth_info.lsa.agid = 0;
847 i_error = ioctl( i_fd, DVD_AUTH, &auth_info );
850 /* No error during ioctl: we know if device
851 * is authenticated */
855 intf_ErrMsg( "CSS: AGID N/A, invalidating" );
856 auth_info.type = DVD_INVALIDATE_AGID;
857 auth_info.lsa.agid = 0;
858 ioctl( i_fd, DVD_AUTH, &auth_info );
861 /* Unable to authenticate without AGID */
865 intf_ErrMsg( "CSS: Cannot get AGID" );
869 for( i = 0 ; i < 10; ++i )
871 css.disc.pi_challenge[i] = i;
874 /* Send AGID to host */
875 auth_info.type = DVD_HOST_SEND_CHALLENGE;
877 /* Get challenge from host */
878 for( i = 0 ; i < 10 ; ++i )
880 auth_info.hsc.chal[9-i] = css.disc.pi_challenge[i];
882 /* Returning data, let LU change state */
883 css.i_agid = auth_info.lsa.agid;
885 /* Send challenge to LU */
886 if( ioctl( i_fd, DVD_AUTH, &auth_info )<0 )
888 intf_ErrMsg( "CSS: Send challenge to LU failed ");
893 /* Get key1 from LU */
894 if( ioctl( i_fd, DVD_AUTH, &auth_info ) < 0)
896 intf_ErrMsg( "CSS: Get key1 from LU failed ");
901 /* Send key1 to host */
902 for( i = 0 ; i < KEY_SIZE ; i++ )
904 css.disc.pi_key1[i] = auth_info.lsk.key[4-i];
907 for( i = 0 ; i < 32 ; ++i )
909 CSSCryptKey( 0, i, css.disc.pi_challenge,
910 css.disc.pi_key_check );
912 if( memcmp( css.disc.pi_key_check,
913 css.disc.pi_key1, KEY_SIZE ) == 0 )
915 intf_WarnMsg( 3, "CSS: Drive Authentic - using varient %d", i);
916 css.disc.i_varient = i;
917 auth_info.type = DVD_LU_SEND_CHALLENGE;
924 intf_ErrMsg( "Drive would not Authenticate" );
925 auth_info.type = DVD_AUTH_FAILURE;
930 /* Get challenge from LU */
931 if( ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
933 intf_ErrMsg( "CSS: Get challenge from LU failed ");
938 /* Send challenge to host */
939 for( i = 0 ; i < 10 ; ++i )
941 css.disc.pi_challenge[i] = auth_info.hsc.chal[9-i];
944 CSSCryptKey( 1, css.disc.i_varient, css.disc.pi_challenge,
946 auth_info.type = DVD_HOST_SEND_KEY2;
948 /* Get key2 from host */
949 for( i = 0 ; i < KEY_SIZE ; ++i )
951 auth_info.hsk.key[4-i] = css.disc.pi_key2[i];
953 /* Returning data, let LU change state */
955 /* Send key2 to LU */
956 if( ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
958 intf_ErrMsg( "CSS: Send key2 to LU failed (expected)" );
962 if( auth_info.type == DVD_AUTH_ESTABLISHED )
964 intf_WarnMsg( 3, "CSS: Authentication established");
966 else if( auth_info.type == DVD_AUTH_FAILURE )
969 intf_ErrMsg("CSS: DVD authentication failed");
972 memcpy( css.disc.pi_challenge, css.disc.pi_key1, KEY_SIZE );
973 memcpy( css.disc.pi_challenge+KEY_SIZE, css.disc.pi_key2, KEY_SIZE );
974 CSSCryptKey( 2, css.disc.i_varient,
975 css.disc.pi_challenge,
976 css.disc.pi_key_check );
978 intf_WarnMsg( 1, "CSS: Received Session Key" );
986 /* Test authentication success */
987 switch( CSSGetASF( i_fd ) )
994 intf_WarnMsg( 3, "CSS: Getting disc key" );
997 /* Get encrypted disc key */
998 dvd.type = DVD_STRUCT_DISCKEY;
999 dvd.disckey.agid = css.i_agid;
1000 memset( dvd.disckey.value, 0, 2048 );
1002 if( ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
1004 intf_ErrMsg( "CSS: Could not read Disc Key" );
1009 /* Unencrypt disc key using bus key */
1010 for( i = 0 ; i < sizeof(dvd.disckey.value) ; i++ )
1012 dvd.disckey.value[i] ^= css.disc.pi_key_check[4 - (i % KEY_SIZE)];
1014 memcpy( css.disc.pi_key_check, dvd.disckey.value, 2048 );
1016 /* Test authentication success */
1017 switch( CSSGetASF( i_fd ) )
1029 /*****************************************************************************
1030 * CSSGetKeys : get the title keys.
1031 * The DVD should have been opened and authenticated before.
1032 *****************************************************************************/
1033 int CSSGetKeys( css_t * p_css )
1036 * Title key cracking method from Ethan Hawke,
1037 * with Frank A. Stevenson algorithm.
1038 * Does not use any player key table and ioctls.
1042 title_key_t p_title_key[10] ;
1044 boolean_t b_encrypted;
1045 boolean_t b_stop_scanning;
1050 int i_registered_keys;
1051 int i_total_keys_found;
1055 for( i_title = 0 ; i_title < p_css->i_title_nb ; i_title++ )
1057 /* Initialization for each title */
1058 memset( p_title_key, 0, 10 );
1059 memset( &key, 0, 10 );
1061 b_stop_scanning = 0;
1062 i_registered_keys = 0 ;
1063 i_total_keys_found = 0 ;
1066 /* Position of the title on the disc */
1067 i_pos = p_css->p_title_key[i_title].i;
1069 //fprintf( stderr, "CSS %d start pos: %lld\n", i_title, i_pos );
1072 i_pos = lseek( p_css->i_fd, i_pos, SEEK_SET );
1073 i_bytes_read = read( p_css->i_fd, pi_buf, 0x800 );
1075 /* PES_scrambling_control */
1076 if( pi_buf[0x14] & 0x30 )
1082 for( i = 2 ; i < 0x30 ; i++ )
1084 for( j = i ; ( j < 0x80 ) &&
1085 ( pi_buf[0x7F - (j%i)] == pi_buf[0x7F-j] ) ; j++ );
1087 if( ( j > i_best_plen ) && ( j > i ) )
1095 if( ( i_best_plen > 20 ) && ( i_best_plen / i_best_p >= 2) )
1097 i = CSSCracker( 0, &pi_buf[0x80],
1098 &pi_buf[0x80 - ( i_best_plen / i_best_p) *i_best_p],
1099 (DVD_key_t*)&pi_buf[0x54],
1104 for( j=0 ; j<i_registered_keys ; j++ )
1106 if( memcmp( &(p_title_key[j].key),
1107 &key, sizeof(DVD_key_t) ) == 0 )
1110 i_total_keys_found++;
1117 memcpy( &(p_title_key[i_registered_keys].key),
1118 &key, sizeof(DVD_key_t) );
1119 p_title_key[i_registered_keys++].i = 1;
1120 i_total_keys_found++;
1122 i = CSSCracker( i, &pi_buf[0x80],
1123 &pi_buf[0x80 -( i_best_plen / i_best_p) *i_best_p],
1124 (DVD_key_t*)&pi_buf[0x54], &key);
1127 /* Stop search if we find one occurance of the key
1128 * I have never found a DVD for which it is not enough
1129 * but we should take care of that */
1130 if( i_registered_keys == 1 && p_title_key[0].i >= 1 )
1132 b_stop_scanning = 1;
1137 i_pos += i_bytes_read;
1138 } while( i_bytes_read == 0x800 && !b_stop_scanning);
1140 if( b_stop_scanning)
1143 "CSS: Found enough occurancies of the same key." );
1148 intf_WarnMsg( 3, "CSS: This file was _NOT_ encrypted!");
1152 if( b_encrypted && i_registered_keys == 0 )
1154 intf_ErrMsg( "CSS: Unable to determine keys from file.");
1158 for( i = 0 ; i < i_registered_keys - 1 ; i++ )
1160 for( j = i + 1 ; j < i_registered_keys ; j++ )
1162 if( p_title_key[j].i > p_title_key[i].i )
1164 memcpy( &key, &(p_title_key[j].key), sizeof(DVD_key_t) );
1165 k = p_title_key[j].i;
1167 memcpy( &(p_title_key[j].key),
1168 &(p_title_key[i].key), sizeof(DVD_key_t) );
1169 p_title_key[j].i = p_title_key[i].i;
1171 memcpy( &(p_title_key[i].key),&key, sizeof(DVD_key_t) );
1172 p_title_key[i].i = k;
1178 intf_WarnMsg( 1, " Key(s) & key probability\n---------------------");
1180 for( i=0 ; i<i_registered_keys ; i++ )
1183 intf_WarnMsg( 1, "%d) %02X %02X %02X %02X %02X - %3.2f%%", i,
1184 p_title_key[i].key[0], p_title_key[i].key[1],
1185 p_title_key[i].key[2], p_title_key[i].key[3],
1186 p_title_key[i].key[4],
1187 p_title_key[i].i * 100.0 / i_total_keys_found );
1189 if( p_title_key[i_highest].i * 100.0 / i_total_keys_found
1190 <= p_title_key[i].i*100.0 / i_total_keys_found )
1197 /* The "find the key with the highest probability" code
1198 * is untested, as I haven't been able to find a VOB that
1199 * produces multiple keys (RT)
1201 intf_WarnMsg( 3, "CSS: Title %d key: %02X %02X %02X %02X %02X",
1203 p_title_key[i_highest].key[0],
1204 p_title_key[i_highest].key[1],
1205 p_title_key[i_highest].key[2],
1206 p_title_key[i_highest].key[3],
1207 p_title_key[i_highest].key[4] );
1209 memcpy( p_css->p_title_key[i_title].key,
1210 p_title_key[i_highest].key, KEY_SIZE );
1216 /*****************************************************************************
1217 * CSSDescrambleSector
1219 * sec : sector to descramble
1220 * key : title key for this sector
1221 *****************************************************************************/
1222 int CSSDescrambleSector( DVD_key_t key, u8* pi_sec )
1224 unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
1225 u8* pi_end = pi_sec + 0x800;
1227 /* PES_scrambling_control */
1228 if( pi_sec[0x14] & 0x30)
1230 i_t1 = ((key)[0] ^ pi_sec[0x54]) | 0x100;
1231 i_t2 = (key)[1] ^ pi_sec[0x55];
1232 i_t3 = (((key)[2]) | ((key)[3] << 8) |
1233 ((key)[4] << 16)) ^ ((pi_sec[0x56]) |
1234 (pi_sec[0x57] << 8) | (pi_sec[0x58] << 16));
1236 i_t3 = i_t3 * 2 + 8 - i_t4;
1240 while( pi_sec != pi_end )
1242 i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
1244 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
1245 i_t4 = pi_css_tab5[i_t4];
1246 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
1247 i_t3 ) >> 8 ) ^ i_t3 ) >> 5) & 0xff;
1248 i_t3 = (i_t3 << 8 ) | i_t6;
1249 i_t6 = pi_css_tab4[i_t6];
1250 i_t5 += i_t6 + i_t4;
1251 *pi_sec++ = pi_css_tab1[*pi_sec] ^( i_t5 & 0xff );