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.7 2001/02/13 10:08:51 stef Exp $
7 * Author: Stéphane Borel <stef@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
29 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
35 #include <netinet/in.h>
36 #ifdef HAVE_SYS_IOCTL_H
37 # include <sys/ioctl.h>
39 #ifdef HAVE_SYS_DVDIO_H
40 # include <sys/dvdio.h>
43 # include <linux/cdrom.h>
50 #include "input_dvd.h"
52 /*****************************************************************************
54 *****************************************************************************/
55 static u8 pi_css_tab1[256]=
56 { 0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76,
57 0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b,
58 0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96,
59 0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b,
60 0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12,
61 0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f,
62 0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90,
63 0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91,
64 0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74,
65 0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75,
66 0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94,
67 0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95,
68 0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10,
69 0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11,
70 0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92,
71 0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f,
72 0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16,
73 0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b,
74 0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6,
75 0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb,
76 0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72,
77 0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f,
78 0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0,
79 0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1,
80 0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14,
81 0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15,
82 0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4,
83 0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5,
84 0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70,
85 0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71,
86 0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2,
87 0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff
90 static u8 pi_css_tab2[256]=
91 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
92 0x09, 0x08, 0x0b, 0x0a, 0x0d, 0x0c, 0x0f, 0x0e,
93 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15,
94 0x1b, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x1d, 0x1c,
95 0x24, 0x25, 0x26, 0x27, 0x20, 0x21, 0x22, 0x23,
96 0x2d, 0x2c, 0x2f, 0x2e, 0x29, 0x28, 0x2b, 0x2a,
97 0x36, 0x37, 0x34, 0x35, 0x32, 0x33, 0x30, 0x31,
98 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
99 0x49, 0x48, 0x4b, 0x4a, 0x4d, 0x4c, 0x4f, 0x4e,
100 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
101 0x5b, 0x5a, 0x59, 0x58, 0x5f, 0x5e, 0x5d, 0x5c,
102 0x52, 0x53, 0x50, 0x51, 0x56, 0x57, 0x54, 0x55,
103 0x6d, 0x6c, 0x6f, 0x6e, 0x69, 0x68, 0x6b, 0x6a,
104 0x64, 0x65, 0x66, 0x67, 0x60, 0x61, 0x62, 0x63,
105 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
106 0x76, 0x77, 0x74, 0x75, 0x72, 0x73, 0x70, 0x71,
107 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95,
108 0x9b, 0x9a, 0x99, 0x98, 0x9f, 0x9e, 0x9d, 0x9c,
109 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
110 0x89, 0x88, 0x8b, 0x8a, 0x8d, 0x8c, 0x8f, 0x8e,
111 0xb6, 0xb7, 0xb4, 0xb5, 0xb2, 0xb3, 0xb0, 0xb1,
112 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
113 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3,
114 0xad, 0xac, 0xaf, 0xae, 0xa9, 0xa8, 0xab, 0xaa,
115 0xdb, 0xda, 0xd9, 0xd8, 0xdf, 0xde, 0xdd, 0xdc,
116 0xd2, 0xd3, 0xd0, 0xd1, 0xd6, 0xd7, 0xd4, 0xd5,
117 0xc9, 0xc8, 0xcb, 0xca, 0xcd, 0xcc, 0xcf, 0xce,
118 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
119 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
120 0xf6, 0xf7, 0xf4, 0xf5, 0xf2, 0xf3, 0xf0, 0xf1,
121 0xed, 0xec, 0xef, 0xee, 0xe9, 0xe8, 0xeb, 0xea,
122 0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3
125 static u8 pi_css_tab3[512]=
126 { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
127 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
128 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
129 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
130 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
131 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
132 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
133 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
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
192 static u8 pi_css_tab4[256]=
193 { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
194 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
195 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
196 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
197 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
198 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
199 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
200 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
201 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
202 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
203 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
204 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
205 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
206 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
207 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
208 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
209 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
210 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
211 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
212 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
213 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
214 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
215 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
216 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
217 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
218 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
219 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
220 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
221 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
222 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
223 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
224 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
227 static u8 pi_css_tab5[256]=
228 { 0xff, 0x7f, 0xbf, 0x3f, 0xdf, 0x5f, 0x9f, 0x1f,
229 0xef, 0x6f, 0xaf, 0x2f, 0xcf, 0x4f, 0x8f, 0x0f,
230 0xf7, 0x77, 0xb7, 0x37, 0xd7, 0x57, 0x97, 0x17,
231 0xe7, 0x67, 0xa7, 0x27, 0xc7, 0x47, 0x87, 0x07,
232 0xfb, 0x7b, 0xbb, 0x3b, 0xdb, 0x5b, 0x9b, 0x1b,
233 0xeb, 0x6b, 0xab, 0x2b, 0xcb, 0x4b, 0x8b, 0x0b,
234 0xf3, 0x73, 0xb3, 0x33, 0xd3, 0x53, 0x93, 0x13,
235 0xe3, 0x63, 0xa3, 0x23, 0xc3, 0x43, 0x83, 0x03,
236 0xfd, 0x7d, 0xbd, 0x3d, 0xdd, 0x5d, 0x9d, 0x1d,
237 0xed, 0x6d, 0xad, 0x2d, 0xcd, 0x4d, 0x8d, 0x0d,
238 0xf5, 0x75, 0xb5, 0x35, 0xd5, 0x55, 0x95, 0x15,
239 0xe5, 0x65, 0xa5, 0x25, 0xc5, 0x45, 0x85, 0x05,
240 0xf9, 0x79, 0xb9, 0x39, 0xd9, 0x59, 0x99, 0x19,
241 0xe9, 0x69, 0xa9, 0x29, 0xc9, 0x49, 0x89, 0x09,
242 0xf1, 0x71, 0xb1, 0x31, 0xd1, 0x51, 0x91, 0x11,
243 0xe1, 0x61, 0xa1, 0x21, 0xc1, 0x41, 0x81, 0x01,
244 0xfe, 0x7e, 0xbe, 0x3e, 0xde, 0x5e, 0x9e, 0x1e,
245 0xee, 0x6e, 0xae, 0x2e, 0xce, 0x4e, 0x8e, 0x0e,
246 0xf6, 0x76, 0xb6, 0x36, 0xd6, 0x56, 0x96, 0x16,
247 0xe6, 0x66, 0xa6, 0x26, 0xc6, 0x46, 0x86, 0x06,
248 0xfa, 0x7a, 0xba, 0x3a, 0xda, 0x5a, 0x9a, 0x1a,
249 0xea, 0x6a, 0xaa, 0x2a, 0xca, 0x4a, 0x8a, 0x0a,
250 0xf2, 0x72, 0xb2, 0x32, 0xd2, 0x52, 0x92, 0x12,
251 0xe2, 0x62, 0xa2, 0x22, 0xc2, 0x42, 0x82, 0x02,
252 0xfc, 0x7c, 0xbc, 0x3c, 0xdc, 0x5c, 0x9c, 0x1c,
253 0xec, 0x6c, 0xac, 0x2c, 0xcc, 0x4c, 0x8c, 0x0c,
254 0xf4, 0x74, 0xb4, 0x34, 0xd4, 0x54, 0x94, 0x14,
255 0xe4, 0x64, 0xa4, 0x24, 0xc4, 0x44, 0x84, 0x04,
256 0xf8, 0x78, 0xb8, 0x38, 0xd8, 0x58, 0x98, 0x18,
257 0xe8, 0x68, 0xa8, 0x28, 0xc8, 0x48, 0x88, 0x08,
258 0xf0, 0x70, 0xb0, 0x30, 0xd0, 0x50, 0x90, 0x10,
259 0xe0, 0x60, 0xa0, 0x20, 0xc0, 0x40, 0x80, 0x00
262 /* Mangle tables usesd for key decryption */
263 static u8 pi_css_mangle0[256] =
265 0x00, 0x81, 0x03, 0x82, 0x06, 0x87, 0x05, 0x84,
266 0x0C, 0x8D, 0x0F, 0x8E, 0x0A, 0x8B, 0x09, 0x88,
267 0x18, 0x99, 0x1B, 0x9A, 0x1E, 0x9F, 0x1D, 0x9C,
268 0x14, 0x95, 0x17, 0x96, 0x12, 0x93, 0x11, 0x90,
269 0x30, 0xB1, 0x33, 0xB2, 0x36, 0xB7, 0x35, 0xB4,
270 0x3C, 0xBD, 0x3F, 0xBE, 0x3A, 0xBB, 0x39, 0xB8,
271 0x28, 0xA9, 0x2B, 0xAA, 0x2E, 0xAF, 0x2D, 0xAC,
272 0x24, 0xA5, 0x27, 0xA6, 0x22, 0xA3, 0x21, 0xA0,
273 0x60, 0xE1, 0x63, 0xE2, 0x66, 0xE7, 0x65, 0xE4,
274 0x6C, 0xED, 0x6F, 0xEE, 0x6A, 0xEB, 0x69, 0xE8,
275 0x78, 0xF9, 0x7B, 0xFA, 0x7E, 0xFF, 0x7D, 0xFC,
276 0x74, 0xF5, 0x77, 0xF6, 0x72, 0xF3, 0x71, 0xF0,
277 0x50, 0xD1, 0x53, 0xD2, 0x56, 0xD7, 0x55, 0xD4,
278 0x5C, 0xDD, 0x5F, 0xDE, 0x5A, 0xDB, 0x59, 0xD8,
279 0x48, 0xC9, 0x4B, 0xCA, 0x4E, 0xCF, 0x4D, 0xCC,
280 0x44, 0xC5, 0x47, 0xC6, 0x42, 0xC3, 0x41, 0xC0,
281 0xC0, 0x41, 0xC3, 0x42, 0xC6, 0x47, 0xC5, 0x44,
282 0xCC, 0x4D, 0xCF, 0x4E, 0xCA, 0x4B, 0xC9, 0x48,
283 0xD8, 0x59, 0xDB, 0x5A, 0xDE, 0x5F, 0xDD, 0x5C,
284 0xD4, 0x55, 0xD7, 0x56, 0xD2, 0x53, 0xD1, 0x50,
285 0xF0, 0x71, 0xF3, 0x72, 0xF6, 0x77, 0xF5, 0x74,
286 0xFC, 0x7D, 0xFF, 0x7E, 0xFA, 0x7B, 0xF9, 0x78,
287 0xE8, 0x69, 0xEB, 0x6A, 0xEE, 0x6F, 0xED, 0x6C,
288 0xE4, 0x65, 0xE7, 0x66, 0xE2, 0x63, 0xE1, 0x60,
289 0xA0, 0x21, 0xA3, 0x22, 0xA6, 0x27, 0xA5, 0x24,
290 0xAC, 0x2D, 0xAF, 0x2E, 0xAA, 0x2B, 0xA9, 0x28,
291 0xB8, 0x39, 0xBB, 0x3A, 0xBE, 0x3F, 0xBD, 0x3C,
292 0xB4, 0x35, 0xB7, 0x36, 0xB2, 0x33, 0xB1, 0x30,
293 0x90, 0x11, 0x93, 0x12, 0x96, 0x17, 0x95, 0x14,
294 0x9C, 0x1D, 0x9F, 0x1E, 0x9A, 0x1B, 0x99, 0x18,
295 0x88, 0x09, 0x8B, 0x0A, 0x8E, 0x0F, 0x8D, 0x0C,
296 0x84, 0x05, 0x87, 0x06, 0x82, 0x03, 0x81, 0x00
299 static u8 pi_css_mangle1[256] =
301 0xC4, 0xCD, 0xCE, 0xCB, 0xC8, 0xC9, 0xCA, 0xCF,
302 0xCC, 0xC5, 0xC6, 0xC3, 0xC0, 0xC1, 0xC2, 0xC7,
303 0x14, 0x1D, 0x1E, 0x1B, 0x18, 0x19, 0x1A, 0x1F,
304 0x1C, 0x15, 0x16, 0x13, 0x10, 0x11, 0x12, 0x17,
305 0x24, 0x2D, 0x2E, 0x2B, 0x28, 0x29, 0x2A, 0x2F,
306 0x2C, 0x25, 0x26, 0x23, 0x20, 0x21, 0x22, 0x27,
307 0x34, 0x3D, 0x3E, 0x3B, 0x38, 0x39, 0x3A, 0x3F,
308 0x3C, 0x35, 0x36, 0x33, 0x30, 0x31, 0x32, 0x37,
309 0x04, 0x0D, 0x0E, 0x0B, 0x08, 0x09, 0x0A, 0x0F,
310 0x0C, 0x05, 0x06, 0x03, 0x00, 0x01, 0x02, 0x07,
311 0xD4, 0xDD, 0xDE, 0xDB, 0xD8, 0xD9, 0xDA, 0xDF,
312 0xDC, 0xD5, 0xD6, 0xD3, 0xD0, 0xD1, 0xD2, 0xD7,
313 0xE4, 0xED, 0xEE, 0xEB, 0xE8, 0xE9, 0xEA, 0xEF,
314 0xEC, 0xE5, 0xE6, 0xE3, 0xE0, 0xE1, 0xE2, 0xE7,
315 0xF4, 0xFD, 0xFE, 0xFB, 0xF8, 0xF9, 0xFA, 0xFF,
316 0xFC, 0xF5, 0xF6, 0xF3, 0xF0, 0xF1, 0xF2, 0xF7,
317 0x44, 0x4D, 0x4E, 0x4B, 0x48, 0x49, 0x4A, 0x4F,
318 0x4C, 0x45, 0x46, 0x43, 0x40, 0x41, 0x42, 0x47,
319 0x94, 0x9D, 0x9E, 0x9B, 0x98, 0x99, 0x9A, 0x9F,
320 0x9C, 0x95, 0x96, 0x93, 0x90, 0x91, 0x92, 0x97,
321 0xA4, 0xAD, 0xAE, 0xAB, 0xA8, 0xA9, 0xAA, 0xAF,
322 0xAC, 0xA5, 0xA6, 0xA3, 0xA0, 0xA1, 0xA2, 0xA7,
323 0xB4, 0xBD, 0xBE, 0xBB, 0xB8, 0xB9, 0xBA, 0xBF,
324 0xBC, 0xB5, 0xB6, 0xB3, 0xB0, 0xB1, 0xB2, 0xB7,
325 0x84, 0x8D, 0x8E, 0x8B, 0x88, 0x89, 0x8A, 0x8F,
326 0x8C, 0x85, 0x86, 0x83, 0x80, 0x81, 0x82, 0x87,
327 0x54, 0x5D, 0x5E, 0x5B, 0x58, 0x59, 0x5A, 0x5F,
328 0x5C, 0x55, 0x56, 0x53, 0x50, 0x51, 0x52, 0x57,
329 0x64, 0x6D, 0x6E, 0x6B, 0x68, 0x69, 0x6A, 0x6F,
330 0x6C, 0x65, 0x66, 0x63, 0x60, 0x61, 0x62, 0x67,
331 0x74, 0x7D, 0x7E, 0x7B, 0x78, 0x79, 0x7A, 0x7F,
332 0x7C, 0x75, 0x76, 0x73, 0x70, 0x71, 0x72, 0x77
335 static u8 pi_css_mangle2[256] =
337 0xC4, 0x24, 0x14, 0x34, 0xCE, 0x2E, 0x1E, 0x3E,
338 0xCD, 0x2D, 0x1D, 0x3D, 0xCB, 0x2B, 0x1B, 0x3B,
339 0x44, 0xA4, 0x94, 0xB4, 0x4E, 0xAE, 0x9E, 0xBE,
340 0x4D, 0xAD, 0x9D, 0xBD, 0x4B, 0xAB, 0x9B, 0xBB,
341 0x04, 0xE4, 0xD4, 0xF4, 0x0E, 0xEE, 0xDE, 0xFE,
342 0x0D, 0xED, 0xDD, 0xFD, 0x0B, 0xEB, 0xDB, 0xFB,
343 0x84, 0x64, 0x54, 0x74, 0x8E, 0x6E, 0x5E, 0x7E,
344 0x8D, 0x6D, 0x5D, 0x7D, 0x8B, 0x6B, 0x5B, 0x7B,
345 0xCC, 0x2C, 0x1C, 0x3C, 0xC6, 0x26, 0x16, 0x36,
346 0xC5, 0x25, 0x15, 0x35, 0xC3, 0x23, 0x13, 0x33,
347 0x4C, 0xAC, 0x9C, 0xBC, 0x46, 0xA6, 0x96, 0xB6,
348 0x45, 0xA5, 0x95, 0xB5, 0x43, 0xA3, 0x93, 0xB3,
349 0x0C, 0xEC, 0xDC, 0xFC, 0x06, 0xE6, 0xD6, 0xF6,
350 0x05, 0xE5, 0xD5, 0xF5, 0x03, 0xE3, 0xD3, 0xF3,
351 0x8C, 0x6C, 0x5C, 0x7C, 0x86, 0x66, 0x56, 0x76,
352 0x85, 0x65, 0x55, 0x75, 0x83, 0x63, 0x53, 0x73,
353 0xC8, 0x28, 0x18, 0x38, 0xCA, 0x2A, 0x1A, 0x3A,
354 0xC9, 0x29, 0x19, 0x39, 0xCF, 0x2F, 0x1F, 0x3F,
355 0x48, 0xA8, 0x98, 0xB8, 0x4A, 0xAA, 0x9A, 0xBA,
356 0x49, 0xA9, 0x99, 0xB9, 0x4F, 0xAF, 0x9F, 0xBF,
357 0x08, 0xE8, 0xD8, 0xF8, 0x0A, 0xEA, 0xDA, 0xFA,
358 0x09, 0xE9, 0xD9, 0xF9, 0x0F, 0xEF, 0xDF, 0xFF,
359 0x88, 0x68, 0x58, 0x78, 0x8A, 0x6A, 0x5A, 0x7A,
360 0x89, 0x69, 0x59, 0x79, 0x8F, 0x6F, 0x5F, 0x7F,
361 0xC0, 0x20, 0x10, 0x30, 0xC2, 0x22, 0x12, 0x32,
362 0xC1, 0x21, 0x11, 0x31, 0xC7, 0x27, 0x17, 0x37,
363 0x40, 0xA0, 0x90, 0xB0, 0x42, 0xA2, 0x92, 0xB2,
364 0x41, 0xA1, 0x91, 0xB1, 0x47, 0xA7, 0x97, 0xB7,
365 0x00, 0xE0, 0xD0, 0xF0, 0x02, 0xE2, 0xD2, 0xF2,
366 0x01, 0xE1, 0xD1, 0xF1, 0x07, 0xE7, 0xD7, 0xF7,
367 0x80, 0x60, 0x50, 0x70, 0x82, 0x62, 0x52, 0x72,
368 0x81, 0x61, 0x51, 0x71, 0x87, 0x67, 0x57, 0x77
371 static u8 pi_reverse[256] =
373 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
374 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
375 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
376 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
377 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
378 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
379 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
380 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
381 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
382 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
383 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
384 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
385 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
386 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
387 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
388 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
389 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
390 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
391 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
392 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
393 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
394 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
395 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
396 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
397 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
398 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
399 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
400 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
401 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
402 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
403 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
404 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
411 /*****************************************************************************
412 * CSSGetASF : Get Authentification success flag
416 * 0 if the device needs to be authenticated,
418 *****************************************************************************/
419 static int CSSGetASF( int i_fd )
421 dvd_authinfo auth_info;
423 auth_info.type = DVD_LU_SEND_ASF;
424 auth_info.lsasf.asf = 0;
426 for( auth_info.lsasf.agid = 0 ; auth_info.lsasf.agid < 4 ;
427 auth_info.lsasf.agid++ )
429 if( !( ioctl( i_fd, DVD_AUTH, &auth_info ) ) )
431 intf_WarnMsg( 3, "CSS: %sAuthenticated",
432 ( auth_info.lsasf.asf ) ? "" : "not " );
433 return auth_info.lsasf.asf;
437 /* The ioctl process has failed */
438 intf_ErrMsg( "CSS: GetASF Fatal Error" );
442 /*****************************************************************************
443 * CSSCryptKey : shuffles bits and unencrypt keys.
444 * Used during authentication and disc key negociation in CSSInit.
446 * i_key_type : 0->key1, 1->key2, 2->buskey.
447 * i_varient : between 0 and 31.
448 *****************************************************************************/
449 static void CSSCryptKey( int i_key_type, int i_varient,
450 u8 const * pi_challenge, u8* pi_key )
453 u8 pi_css_secret[5] = { 0xE2, 0xA3, 0x45, 0x10, 0xF4 };
455 /* Permutation table for challenge */
456 u8 ppi_perm_challenge[3][10] =
457 { { 1, 3, 0, 7, 5, 2, 9, 6, 4, 8 },
458 { 6, 1, 9, 3, 8, 5, 7, 4, 0, 2 },
459 { 4, 0, 3, 5, 7, 2, 8, 6, 1, 9 } };
461 /* Permutation table for varient table for key2 and buskey */
462 u8 ppi_perm_varient[2][32] =
463 { { 0x0a, 0x08, 0x0e, 0x0c, 0x0b, 0x09, 0x0f, 0x0d,
464 0x1a, 0x18, 0x1e, 0x1c, 0x1b, 0x19, 0x1f, 0x1d,
465 0x02, 0x00, 0x06, 0x04, 0x03, 0x01, 0x07, 0x05,
466 0x12, 0x10, 0x16, 0x14, 0x13, 0x11, 0x17, 0x15 },
467 { 0x12, 0x1a, 0x16, 0x1e, 0x02, 0x0a, 0x06, 0x0e,
468 0x10, 0x18, 0x14, 0x1c, 0x00, 0x08, 0x04, 0x0c,
469 0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f,
470 0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d } };
472 /* CSS varient for mangling */
473 u8 pi_css_varients[32] =
474 { 0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15,
475 0x20, 0x21, 0x24, 0x25, 0x30, 0x31, 0x34, 0x35,
476 0x80, 0x81, 0x84, 0x85, 0x90, 0x91, 0x94, 0x95,
477 0xA0, 0xA1, 0xA4, 0xA5, 0xB0, 0xB1, 0xB4, 0xB5 };
491 for( i=0 ; i<10 ; i++ )
493 pi_scratch[i] = pi_challenge[ppi_perm_challenge[i_key_type][i]];
495 i_css_varient = i_key_type == 0 ? i_varient
496 : ppi_perm_varient[i_key_type-1][i_varient];
498 for( i=0 ; i<5 ; i++ )
500 pi_tmp1[i] = pi_scratch[5+i] ^ pi_css_secret[i];
503 /* In order to ensure that the LFSR works we need to ensure that the
504 * initial values are non-zero. Thus when we initialise them from
505 * the seed, we ensure that a bit is set.
507 i_lfsr0 = ( pi_tmp1[0] << 17 ) | ( pi_tmp1[1] << 9 ) |
508 ( ( pi_tmp1[2] & ~7 ) << 1 ) | 8 | (pi_tmp1[2] & 7);
512 * reverse lfsr0/1 to simplify calculation in loop
514 i_lfsr0 = ( pi_reverse[i_lfsr0 & 0xff] << 17 ) |
515 ( pi_reverse[( i_lfsr0 >> 8 ) & 0xff] << 9 ) |
516 ( pi_reverse[( i_lfsr0 >> 16 ) & 0xff] << 1) |
519 i_lfsr1 = ( pi_reverse[pi_tmp1[4]] << 9 ) | 0x100 |
520 ( pi_reverse[pi_tmp1[3]] );
522 i_index = sizeof( pi_bits );
526 i_lfsr0_o = ( i_lfsr0 >> 12) ^ ( i_lfsr0 >> 4) ^
527 ( i_lfsr0 >> 3) ^ i_lfsr0;
529 i_lfsr1_o = ( ( i_lfsr1 >> 14 ) & 7) ^ i_lfsr1;
530 i_lfsr1_o ^= ( i_lfsr1_o << 3 ) ^ ( i_lfsr1_o << 6 );
532 i_lfsr1 = ( i_lfsr1 >> 8) ^ ( i_lfsr1_o << 9);
533 i_lfsr0 = ( i_lfsr0 >> 8 ) ^ ( i_lfsr0_o << 17);
535 i_lfsr0_o = ~i_lfsr0_o;
536 i_lfsr1_o = ~i_lfsr1_o;
538 i_val += i_lfsr0_o + i_lfsr1_o;
540 pi_bits[--i_index] = i_val & 0xFF;
543 } while( i_index > 0 );
545 i_css_varient = pi_css_varients[i_css_varient];
550 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_scratch[i] )
552 i_index = pi_bits[25+i] ^ pi_scratch[i];
553 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
554 pi_tmp1[i] = pi_css_mangle2[i_index] ^ i_term;
556 pi_tmp1[4] ^= pi_tmp1[0];
558 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
560 i_index = pi_bits[20+i] ^ pi_tmp1[i];
561 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
562 pi_tmp2[i] = pi_css_mangle2[i_index] ^ i_term;
564 pi_tmp2[4] ^= pi_tmp2[0];
566 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp2[i] )
568 i_index = pi_bits[15+i] ^ pi_tmp2[i];
569 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
570 i_index = pi_css_mangle2[i_index] ^ i_term;
571 pi_tmp1[i] = pi_css_mangle0[i_index];
573 pi_tmp1[4] ^= pi_tmp1[0];
575 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
577 i_index = pi_bits[10+i] ^ pi_tmp1[i];
578 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
579 i_index = pi_css_mangle2[i_index] ^ i_term;
580 pi_tmp2[i] = pi_css_mangle0[i_index];
582 pi_tmp2[4] ^= pi_tmp2[0];
584 for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp2[i] )
586 i_index = pi_bits[5+i] ^ pi_tmp2[i];
587 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
588 pi_tmp1[i] = pi_css_mangle2[i_index] ^ i_term;
590 pi_tmp1[4] ^= pi_tmp1[0];
592 for( i=5, i_term=0 ; --i>=0 ; i_term=pi_tmp1[i] )
594 i_index = pi_bits[i] ^ pi_tmp1[i];
595 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
596 pi_key[i] = pi_css_mangle2[i_index] ^ i_term;
602 /*****************************************************************************
603 * CSSCracker : title key decryption by cracking
605 * This function is called by CSSGetKeys to find a key
606 *****************************************************************************/
607 static int CSSCracker( int i_start,
608 unsigned char * p_crypted,
609 unsigned char * p_decrypted,
610 DVD_key_t * p_sector_key,
613 unsigned char pi_buffer[10];
614 unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
616 unsigned int i_candidate;
621 for( i = 0 ; i < 10 ; i++ )
623 pi_buffer[i] = pi_css_tab1[p_crypted[i]] ^ p_decrypted[i];
626 for( i_try = i_start ; i_try < 0x10000 ; i_try++ )
628 i_t1 = i_try >> 8 | 0x100;
630 i_t3 = 0; /* not needed */
633 /* iterate cipher 4 times to reconstruct LFSR2 */
634 for( i = 0 ; i < 4 ; i++ )
636 /* advance LFSR1 normaly */
637 i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
639 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
640 i_t4 = pi_css_tab5[i_t4];
641 /* deduce i_t6 & i_t5 */
645 i_t6 = ( i_t6 + 0xff ) & 0x0ff;
653 i_t6 = pi_css_tab4[ i_t6 ];
654 /* feed / advance i_t3 / i_t5 */
655 i_t3 = ( i_t3 << 8 ) | i_t6;
661 /* iterate 6 more times to validate candidate key */
662 for( ; i < 10 ; i++ )
664 i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
666 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
667 i_t4 = pi_css_tab5[i_t4];
668 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
669 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
670 i_t3 = ( i_t3 << 8 ) | i_t6;
671 i_t6 = pi_css_tab4[i_t6];
673 if( ( i_t5 & 0xff ) != pi_buffer[i] )
683 /* Do 4 backwards steps of iterating t3 to deduce initial state */
685 for( i = 0 ; i < 4 ; i++ )
688 i_t3 = ( i_t3 >> 8 );
689 /* easy to code, and fast enough bruteforce
690 * search for byte shifted in */
691 for( j = 0 ; j < 256 ; j++ )
693 i_t3 = ( i_t3 & 0x1ffff) | ( j << 17 );
694 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
695 i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
703 i_t4 = ( i_t3 >> 1 ) - 4;
704 for( i_t5 = 0 ; i_t5 < 8; i_t5++ )
706 if( ( ( i_t4 + i_t5 ) * 2 + 8 - ( (i_t4 + i_t5 ) & 7 ) )
709 (*p_key)[0] = i_try>>8;
710 (*p_key)[1] = i_try & 0xFF;
711 (*p_key)[2] = ( ( i_t4 + i_t5 ) >> 0) & 0xFF;
712 (*p_key)[3] = ( ( i_t4 + i_t5 ) >> 8) & 0xFF;
713 (*p_key)[4] = ( ( i_t4 + i_t5 ) >> 16) & 0xFF;
722 (*p_key)[0] ^= (*p_sector_key)[0];
723 (*p_key)[1] ^= (*p_sector_key)[1];
724 (*p_key)[2] ^= (*p_sector_key)[2];
725 (*p_key)[3] ^= (*p_sector_key)[3];
726 (*p_key)[4] ^= (*p_sector_key)[4];
733 * Authentication and keys
736 /*****************************************************************************
737 * CSSTest : check if the disc is encrypted or not
738 *****************************************************************************/
739 int CSSTest( int i_fd )
743 dvd.type = DVD_STRUCT_COPYRIGHT;
744 dvd.copyright.layer_num = 0;
746 if( ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
748 intf_ErrMsg( "DVD ioctl error" );
752 return dvd.copyright.cpst;
755 /*****************************************************************************
756 * CSSInit : CSS Structure initialisation and DVD authentication.
757 * It simulates the mutual authentication between logical unit and host.
759 * Since we don't need the disc key to find the title key, we just run the
760 * basic unavoidable commands to authenticate device and disc.
761 *****************************************************************************/
763 css_t CSSInit( int i_fd )
765 /* structures defined in cdrom.h or dvdio.h */
766 dvd_authinfo auth_info;
776 memset( &auth_info, 0, sizeof(auth_info) );
778 /* Test authentication success */
779 switch( CSSGetASF( i_fd ) )
786 intf_WarnMsg( 3, "CSS: Authenticating" );
789 /* Init sequence, request AGID */
790 for( i = 1; i < 4 ; ++i )
792 intf_WarnMsg( 3, "CSS: Request AGID %d", i );
793 auth_info.type = DVD_LU_SEND_AGID;
794 auth_info.lsa.agid = 0;
795 i_error = ioctl( i_fd, DVD_AUTH, &auth_info );
798 /* No error during ioctl: we know if device
799 * is authenticated */
803 intf_ErrMsg( "CSS: AGID N/A, invalidating" );
804 auth_info.type = DVD_INVALIDATE_AGID;
805 auth_info.lsa.agid = 0;
806 ioctl( i_fd, DVD_AUTH, &auth_info );
809 /* Unable to authenticate without AGID */
813 intf_ErrMsg( "CSS: Cannot get AGID" );
817 for( i = 0 ; i < 10; ++i )
819 css.disc.pi_challenge[i] = i;
822 /* Send AGID to host */
823 auth_info.type = DVD_HOST_SEND_CHALLENGE;
825 /* Get challenge from host */
826 for( i = 0 ; i < 10 ; ++i )
828 auth_info.hsc.chal[9-i] = css.disc.pi_challenge[i];
830 /* Returning data, let LU change state */
831 css.i_agid = auth_info.lsa.agid;
833 /* Send challenge to LU */
834 if( ioctl( i_fd, DVD_AUTH, &auth_info )<0 )
836 intf_ErrMsg( "CSS: Send challenge to LU failed ");
841 /* Get key1 from LU */
842 if( ioctl( i_fd, DVD_AUTH, &auth_info ) < 0)
844 intf_ErrMsg( "CSS: Get key1 from LU failed ");
849 /* Send key1 to host */
850 for( i = 0 ; i < KEY_SIZE ; i++ )
852 css.disc.pi_key1[i] = auth_info.lsk.key[4-i];
855 for( i = 0 ; i < 32 ; ++i )
857 CSSCryptKey( 0, i, css.disc.pi_challenge,
858 css.disc.pi_key_check );
860 if( memcmp( css.disc.pi_key_check,
861 css.disc.pi_key1, KEY_SIZE ) == 0 )
863 intf_WarnMsg( 3, "CSS: Drive Authentic - using varient %d", i);
864 css.disc.i_varient = i;
865 auth_info.type = DVD_LU_SEND_CHALLENGE;
872 intf_ErrMsg( "Drive would not Authenticate" );
873 auth_info.type = DVD_AUTH_FAILURE;
878 /* Get challenge from LU */
879 if( ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
881 intf_ErrMsg( "CSS: Get challenge from LU failed ");
886 /* Send challenge to host */
887 for( i = 0 ; i < 10 ; ++i )
889 css.disc.pi_challenge[i] = auth_info.hsc.chal[9-i];
892 CSSCryptKey( 1, css.disc.i_varient, css.disc.pi_challenge,
894 auth_info.type = DVD_HOST_SEND_KEY2;
896 /* Get key2 from host */
897 for( i = 0 ; i < KEY_SIZE ; ++i )
899 auth_info.hsk.key[4-i] = css.disc.pi_key2[i];
901 /* Returning data, let LU change state */
903 /* Send key2 to LU */
904 if( ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
906 intf_ErrMsg( "CSS: Send key2 to LU failed (expected)" );
910 if( auth_info.type == DVD_AUTH_ESTABLISHED )
912 intf_WarnMsg( 3, "CSS: Authentication established");
914 else if( auth_info.type == DVD_AUTH_FAILURE )
917 intf_ErrMsg("CSS: DVD authentication failed");
920 memcpy( css.disc.pi_challenge, css.disc.pi_key1, KEY_SIZE );
921 memcpy( css.disc.pi_challenge+KEY_SIZE, css.disc.pi_key2, KEY_SIZE );
922 CSSCryptKey( 2, css.disc.i_varient,
923 css.disc.pi_challenge,
924 css.disc.pi_key_check );
926 intf_WarnMsg( 1, "CSS: Received Session Key" );
934 /* Test authentication success */
935 switch( CSSGetASF( i_fd ) )
942 intf_WarnMsg( 3, "CSS: Getting disc key" );
945 /* Get encrypted disc key */
946 dvd.type = DVD_STRUCT_DISCKEY;
947 dvd.disckey.agid = css.i_agid;
948 memset( dvd.disckey.value, 0, 2048 );
950 if( ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
952 intf_ErrMsg( "CSS: Could not read Disc Key" );
957 /* Unencrypt disc key using bus key */
958 for( i = 0 ; i < sizeof(dvd.disckey.value) ; i++ )
960 dvd.disckey.value[i] ^= css.disc.pi_key_check[4 - (i % KEY_SIZE)];
962 memcpy( css.disc.pi_key_check, dvd.disckey.value, 2048 );
964 /* Test authentication success */
965 switch( CSSGetASF( i_fd ) )
977 /*****************************************************************************
978 * CSSGetKeys : get the title keys.
979 * The DVD should have been opened and authenticated before.
980 *****************************************************************************/
981 int CSSGetKeys( css_t * p_css )
984 * Title key cracking method from Ethan Hawke,
985 * with Frank A. Stevenson algorithm.
986 * Does not use any player key table and ioctls.
990 title_key_t p_title_key[10] ;
992 boolean_t b_encrypted;
993 boolean_t b_stop_scanning;
998 int i_registered_keys;
999 int i_total_keys_found;
1003 for( i_title = 0 ; i_title < p_css->i_title_nb ; i_title++ )
1005 /* Initialization for each title */
1006 memset( p_title_key, 0, 10 );
1007 memset( &key, 0, 10 );
1009 b_stop_scanning = 0;
1010 i_registered_keys = 0 ;
1011 i_total_keys_found = 0 ;
1014 /* Position of the title on the disc */
1015 i_pos = p_css->p_title_key[i_title].i;
1017 //fprintf( stderr, "CSS %d start pos: %lld\n", i_title, i_pos );
1020 i_pos = lseek( p_css->i_fd, i_pos, SEEK_SET );
1021 i_bytes_read = read( p_css->i_fd, pi_buf, 0x800 );
1023 /* PES_scrambling_control */
1024 if( pi_buf[0x14] & 0x30 )
1030 for( i = 2 ; i < 0x30 ; i++ )
1032 for( j = i ; ( j < 0x80 ) &&
1033 ( pi_buf[0x7F - (j%i)] == pi_buf[0x7F-j] ) ; j++ );
1035 if( ( j > i_best_plen ) && ( j > i ) )
1043 if( ( i_best_plen > 20 ) && ( i_best_plen / i_best_p >= 2) )
1045 i = CSSCracker( 0, &pi_buf[0x80],
1046 &pi_buf[0x80 - ( i_best_plen / i_best_p) *i_best_p],
1047 (DVD_key_t*)&pi_buf[0x54],
1052 for( j=0 ; j<i_registered_keys ; j++ )
1054 if( memcmp( &(p_title_key[j].key),
1055 &key, sizeof(DVD_key_t) ) == 0 )
1058 i_total_keys_found++;
1065 memcpy( &(p_title_key[i_registered_keys].key),
1066 &key, sizeof(DVD_key_t) );
1067 p_title_key[i_registered_keys++].i = 1;
1068 i_total_keys_found++;
1070 i = CSSCracker( i, &pi_buf[0x80],
1071 &pi_buf[0x80 -( i_best_plen / i_best_p) *i_best_p],
1072 (DVD_key_t*)&pi_buf[0x54], &key);
1075 /* Stop search if we find two occurances of the key */
1076 if( i_registered_keys == 1 && p_title_key[0].i >= 2 )
1078 b_stop_scanning = 1;
1083 i_pos += i_bytes_read;
1084 } while( i_bytes_read == 0x800 && !b_stop_scanning);
1086 if( b_stop_scanning)
1089 "CSS: Found enough occurancies of the same key." );
1094 intf_WarnMsg( 3, "CSS: This file was _NOT_ encrypted!");
1098 if( b_encrypted && i_registered_keys == 0 )
1100 intf_ErrMsg( "CSS: Unable to determine keys from file.");
1104 for( i = 0 ; i < i_registered_keys - 1 ; i++ )
1106 for( j = i + 1 ; j < i_registered_keys ; j++ )
1108 if( p_title_key[j].i > p_title_key[i].i )
1110 memcpy( &key, &(p_title_key[j].key), sizeof(DVD_key_t) );
1111 k = p_title_key[j].i;
1113 memcpy( &(p_title_key[j].key),
1114 &(p_title_key[i].key), sizeof(DVD_key_t) );
1115 p_title_key[j].i = p_title_key[i].i;
1117 memcpy( &(p_title_key[i].key),&key, sizeof(DVD_key_t) );
1118 p_title_key[i].i = k;
1124 intf_WarnMsg( 1, " Key(s) & key probability\n---------------------");
1126 for( i=0 ; i<i_registered_keys ; i++ )
1129 intf_WarnMsg( 1, "%d) %02X %02X %02X %02X %02X - %3.2f%%", i,
1130 p_title_key[i].key[0], p_title_key[i].key[1],
1131 p_title_key[i].key[2], p_title_key[i].key[3],
1132 p_title_key[i].key[4],
1133 p_title_key[i].i * 100.0 / i_total_keys_found );
1135 if( p_title_key[i_highest].i * 100.0 / i_total_keys_found
1136 <= p_title_key[i].i*100.0 / i_total_keys_found )
1143 /* The "find the key with the highest probability" code
1144 * is untested, as I haven't been able to find a VOB that
1145 * produces multiple keys (RT)
1147 intf_WarnMsg( 3, "CSS: Title %d key: %02X %02X %02X %02X %02X",
1149 p_title_key[i_highest].key[0],
1150 p_title_key[i_highest].key[1],
1151 p_title_key[i_highest].key[2],
1152 p_title_key[i_highest].key[3],
1153 p_title_key[i_highest].key[4] );
1155 memcpy( p_css->p_title_key[i_title].key,
1156 p_title_key[i_highest].key, KEY_SIZE );
1162 /*****************************************************************************
1163 * CSSDescrambleSector
1165 * sec : sector to descramble
1166 * key : title key for this sector
1167 *****************************************************************************/
1168 int CSSDescrambleSector( DVD_key_t key, u8* pi_sec )
1170 unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
1171 u8* pi_end = pi_sec + 0x800;
1173 /* PES_scrambling_control */
1174 if( pi_sec[0x14] & 0x30)
1176 i_t1 = ((key)[0] ^ pi_sec[0x54]) | 0x100;
1177 i_t2 = (key)[1] ^ pi_sec[0x55];
1178 i_t3 = (((key)[2]) | ((key)[3] << 8) |
1179 ((key)[4] << 16)) ^ ((pi_sec[0x56]) |
1180 (pi_sec[0x57] << 8) | (pi_sec[0x58] << 16));
1182 i_t3 = i_t3 * 2 + 8 - i_t4;
1186 while( pi_sec != pi_end )
1188 i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
1190 i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
1191 i_t4 = pi_css_tab5[i_t4];
1192 i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
1193 i_t3 ) >> 8 ) ^ i_t3 ) >> 5) & 0xff;
1194 i_t3 = (i_t3 << 8 ) | i_t6;
1195 i_t6 = pi_css_tab4[i_t6];
1196 i_t5 += i_t6 + i_t4;
1197 *pi_sec++ = pi_css_tab1[*pi_sec] ^( i_t5 & 0xff );