]> git.sesse.net Git - vlc/blob - modules/demux/mp4/drms.c
* drms.c: fopen in binary mode. Convenience fix for those that use the DRMS
[vlc] / modules / demux / mp4 / drms.c
1 /*****************************************************************************
2  * drms.c: DRMS
3  *****************************************************************************
4  * Copyright (C) 2004 VideoLAN
5  * $Id$
6  *
7  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8  *          Sam Hocevar <sam@zoy.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #include <stdlib.h>                                      /* malloc(), free() */
26
27 #ifdef WIN32
28 #   include <io.h>
29 #else
30 #   include <stdio.h>
31 #endif
32
33 #include <vlc/vlc.h>
34
35 #ifdef HAVE_ERRNO_H
36 #   include <errno.h>
37 #endif
38
39 #ifdef WIN32
40 #   include <tchar.h>
41 #   include <shlobj.h>
42 #   include <windows.h>
43 #endif
44
45 #ifdef HAVE_SYS_STAT_H
46 #   include <sys/stat.h>
47 #endif
48 #ifdef HAVE_SYS_TYPES_H
49 #   include <sys/types.h>
50 #endif
51
52 /* In Solaris (and perhaps others) PATH_MAX is in limits.h. */
53 #ifdef HAVE_LIMITS_H
54 #   include <limits.h>
55 #endif
56
57 #ifdef SYS_DARWIN
58 #   include <mach/mach.h>
59 #   include <IOKit/IOKitLib.h>
60 #   include <CoreFoundation/CFNumber.h>
61 #endif
62
63 #ifdef HAVE_SYSFS_LIBSYSFS_H
64 #   include <sysfs/libsysfs.h>
65 #endif
66
67 #include "drms.h"
68 #include "drmstables.h"
69
70 #include "libmp4.h"
71
72 /*****************************************************************************
73  * aes_s: AES keys structure
74  *****************************************************************************
75  * This structure stores a set of keys usable for encryption and decryption
76  * with the AES/Rijndael algorithm.
77  *****************************************************************************/
78 struct aes_s
79 {
80     uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
81     uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
82 };
83
84 /*****************************************************************************
85  * md5_s: MD5 message structure
86  *****************************************************************************
87  * This structure stores the static information needed to compute an MD5
88  * hash. It has an extra data buffer to allow non-aligned writes.
89  *****************************************************************************/
90 struct md5_s
91 {
92     uint64_t i_bits;      /* Total written bits */
93     uint32_t p_digest[4]; /* The MD5 digest */
94     uint32_t p_data[16];  /* Buffer to cache non-aligned writes */
95 };
96
97 /*****************************************************************************
98  * shuffle_s: shuffle structure
99  *****************************************************************************
100  * This structure stores the static information needed to shuffle data using
101  * a custom algorithm.
102  *****************************************************************************/
103 struct shuffle_s
104 {
105     uint32_t i_version;
106     uint32_t p_commands[ 20 ];
107     uint32_t p_bordel[ 16 ];
108 };
109
110 /*****************************************************************************
111  * shuffle_ext_s: extended shuffle structure
112  *****************************************************************************
113  * This structure stores the static information needed to shuffle data using
114  * a custom algorithm.
115  *****************************************************************************/
116 struct shuffle_ext_s
117 {
118     uint32_t * p_bordel;
119     uint32_t i_cmd, i_jc, i_tmp;
120 };
121
122 #define SWAP( a, b ) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
123
124 /*****************************************************************************
125  * drms_s: DRMS structure
126  *****************************************************************************
127  * This structure stores the static information needed to decrypt DRMS data.
128  *****************************************************************************/
129 struct drms_s
130 {
131     uint32_t i_user;
132     uint32_t i_key;
133     uint8_t  p_iviv[ 16 ];
134     uint8_t *p_name;
135
136     uint32_t p_key[ 4 ];
137     struct aes_s aes;
138
139     char     psz_homedir[ PATH_MAX ];
140 };
141
142 /*****************************************************************************
143  * Local prototypes
144  *****************************************************************************/
145 static void InitAES       ( struct aes_s *, uint32_t * );
146 static void DecryptAES    ( struct aes_s *, uint32_t *, const uint32_t * );
147
148 static void InitMD5       ( struct md5_s * );
149 static void AddMD5        ( struct md5_s *, const uint8_t *, uint32_t );
150 static void EndMD5        ( struct md5_s * );
151 static void Digest        ( struct md5_s *, uint32_t * );
152
153 static void InitShuffle   ( struct shuffle_s *, uint32_t *, uint32_t );
154 static void DoShuffle     ( struct shuffle_s *, uint32_t *, uint32_t );
155
156 static uint32_t FirstPass ( uint32_t * );
157 static void SecondPass    ( struct shuffle_ext_s * );
158 static uint32_t ThirdPass ( uint32_t * );
159 static void FourthPass    ( uint32_t *, uint32_t );
160 static void FifthPass     ( uint32_t * );
161 static void BigShuffle1   ( struct shuffle_ext_s * );
162 static void BigShuffle2   ( struct shuffle_ext_s * );
163 static void TinyShuffle1  ( uint32_t * );
164 static void TinyShuffle2  ( uint32_t * );
165 static void DoExtShuffle  ( uint32_t * );
166
167 static int GetSystemKey   ( uint32_t *, vlc_bool_t );
168 static int WriteUserKey   ( void *, uint32_t * );
169 static int ReadUserKey    ( void *, uint32_t * );
170 static int GetUserKey     ( void *, uint32_t * );
171
172 static int GetSCIData     ( char *, uint32_t **, uint32_t * );
173 static int HashSystemInfo ( uint32_t * );
174 static int GetiPodID      ( int64_t * );
175
176 #ifdef WORDS_BIGENDIAN
177 /*****************************************************************************
178  * Reverse: reverse byte order
179  *****************************************************************************/
180 static inline void Reverse( uint32_t *p_buffer, int n )
181 {
182     int i;
183
184     for( i = 0; i < n; i++ )
185     {
186         p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
187     }
188 }
189 #    define REVERSE( p, n ) Reverse( p, n )
190 #else
191 #    define REVERSE( p, n )
192 #endif
193
194 /*****************************************************************************
195  * BlockXOR: XOR two 128 bit blocks
196  *****************************************************************************/
197 static inline void BlockXOR( uint32_t *p_dest, uint32_t *p_s1, uint32_t *p_s2 )
198 {
199     int i;
200
201     for( i = 0; i < 4; i++ )
202     {
203         p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
204     }
205 }
206
207 /*****************************************************************************
208  * drms_alloc: allocate a DRMS structure
209  *****************************************************************************/
210 void *drms_alloc( char *psz_homedir )
211 {
212     struct drms_s *p_drms;
213
214     p_drms = malloc( sizeof(struct drms_s) );
215
216     if( p_drms == NULL )
217     {
218         return NULL;
219     }
220
221     memset( p_drms, 0, sizeof(struct drms_s) );
222
223     strncpy( p_drms->psz_homedir, psz_homedir, PATH_MAX );
224     p_drms->psz_homedir[ PATH_MAX - 1 ] = '\0';
225
226     return (void *)p_drms;
227 }
228
229 /*****************************************************************************
230  * drms_free: free a previously allocated DRMS structure
231  *****************************************************************************/
232 void drms_free( void *_p_drms )
233 {
234     struct drms_s *p_drms = (struct drms_s *)_p_drms;
235
236     if( p_drms->p_name != NULL )
237     {
238         free( (void *)p_drms->p_name );
239     }
240
241     free( p_drms );
242 }
243
244 /*****************************************************************************
245  * drms_decrypt: unscramble a chunk of data
246  *****************************************************************************/
247 void drms_decrypt( void *_p_drms, uint32_t *p_buffer, uint32_t i_bytes )
248 {
249     struct drms_s *p_drms = (struct drms_s *)_p_drms;
250     uint32_t p_key[ 4 ];
251     unsigned int i_blocks;
252
253     /* AES is a block cypher, round down the byte count */
254     i_blocks = i_bytes / 16;
255     i_bytes = i_blocks * 16;
256
257     /* Initialise the key */
258     memcpy( p_key, p_drms->p_key, 16 );
259
260     /* Unscramble */
261     while( i_blocks-- )
262     {
263         uint32_t p_tmp[ 4 ];
264
265         REVERSE( p_buffer, 4 );
266         DecryptAES( &p_drms->aes, p_tmp, p_buffer );
267         BlockXOR( p_tmp, p_key, p_tmp );
268
269         /* Use the previous scrambled data as the key for next block */
270         memcpy( p_key, p_buffer, 16 );
271
272         /* Copy unscrambled data back to the buffer */
273         memcpy( p_buffer, p_tmp, 16 );
274         REVERSE( p_buffer, 4 );
275
276         p_buffer += 4;
277     }
278 }
279
280 /*****************************************************************************
281  * drms_init: initialise a DRMS structure
282  *****************************************************************************/
283 int drms_init( void *_p_drms, uint32_t i_type,
284                uint8_t *p_info, uint32_t i_len )
285 {
286     struct drms_s *p_drms = (struct drms_s *)_p_drms;
287     int i_ret = 0;
288
289     switch( i_type )
290     {
291         case FOURCC_user:
292             if( i_len < sizeof(p_drms->i_user) )
293             {
294                 i_ret = -1;
295                 break;
296             }
297
298             p_drms->i_user = U32_AT( p_info );
299             break;
300
301         case FOURCC_key:
302             if( i_len < sizeof(p_drms->i_key) )
303             {
304                 i_ret = -1;
305                 break;
306             }
307
308             p_drms->i_key = U32_AT( p_info );
309             break;
310
311         case FOURCC_iviv:
312             if( i_len < sizeof(p_drms->p_key) )
313             {
314                 i_ret = -1;
315                 break;
316             }
317
318             memcpy( p_drms->p_iviv, p_info, 16 );
319             break;
320
321         case FOURCC_name:
322             p_drms->p_name = strdup( p_info );
323
324             if( p_drms->p_name == NULL )
325             {
326                 i_ret = -1;
327             }
328             break;
329
330         case FOURCC_priv:
331         {
332             uint32_t p_priv[ 64 ];
333             struct md5_s md5;
334
335             if( i_len < 64 )
336             {
337                 i_ret = -1;
338                 break;
339             }
340
341             InitMD5( &md5 );
342             AddMD5( &md5, p_drms->p_name, strlen( p_drms->p_name ) );
343             AddMD5( &md5, p_drms->p_iviv, 16 );
344             EndMD5( &md5 );
345
346             if( GetUserKey( p_drms, p_drms->p_key ) )
347             {
348                 i_ret = -1;
349                 break;
350             }
351
352             InitAES( &p_drms->aes, p_drms->p_key );
353
354             memcpy( p_priv, p_info, 64 );
355             memcpy( p_drms->p_key, md5.p_digest, 16 );
356             drms_decrypt( p_drms, p_priv, 64 );
357             REVERSE( p_priv, 64 );
358
359             if( p_priv[ 0 ] != 0x6e757469 ) /* itun */
360             {
361                 i_ret = -1;
362                 break;
363             }
364
365             InitAES( &p_drms->aes, p_priv + 6 );
366             memcpy( p_drms->p_key, p_priv + 12, 16 );
367
368             free( (void *)p_drms->p_name );
369             p_drms->p_name = NULL;
370         }
371         break;
372     }
373
374     return i_ret;
375 }
376
377 /* The following functions are local */
378
379 /*****************************************************************************
380  * InitAES: initialise AES/Rijndael encryption/decryption tables
381  *****************************************************************************
382  * The Advanced Encryption Standard (AES) is described in RFC 3268
383  *****************************************************************************/
384 static void InitAES( struct aes_s *p_aes, uint32_t *p_key )
385 {
386     unsigned int i, t;
387     uint32_t i_key, i_seed;
388
389     memset( p_aes->pp_enc_keys[1], 0, 16 );
390     memcpy( p_aes->pp_enc_keys[0], p_key, 16 );
391
392     /* Generate the key tables */
393     i_seed = p_aes->pp_enc_keys[ 0 ][ 3 ];
394
395     for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
396     {
397         uint32_t j;
398
399         i_seed = AES_ROR( i_seed, 8 );
400
401         j = p_aes_table[ i_key ];
402
403         j ^= p_aes_encrypt[ (i_seed >> 24) & 0xff ]
404               ^ AES_ROR( p_aes_encrypt[ (i_seed >> 16) & 0xff ], 8 )
405               ^ AES_ROR( p_aes_encrypt[ (i_seed >> 8) & 0xff ], 16 )
406               ^ AES_ROR( p_aes_encrypt[ i_seed & 0xff ], 24 );
407
408         j ^= p_aes->pp_enc_keys[ i_key ][ 0 ];
409         p_aes->pp_enc_keys[ i_key + 1 ][ 0 ] = j;
410         j ^= p_aes->pp_enc_keys[ i_key ][ 1 ];
411         p_aes->pp_enc_keys[ i_key + 1 ][ 1 ] = j;
412         j ^= p_aes->pp_enc_keys[ i_key ][ 2 ];
413         p_aes->pp_enc_keys[ i_key + 1 ][ 2 ] = j;
414         j ^= p_aes->pp_enc_keys[ i_key ][ 3 ];
415         p_aes->pp_enc_keys[ i_key + 1 ][ 3 ] = j;
416
417         i_seed = j;
418     }
419
420     memcpy( p_aes->pp_dec_keys[ 0 ],
421             p_aes->pp_enc_keys[ 0 ], 16 );
422
423     for( i = 1; i < AES_KEY_COUNT; i++ )
424     {
425         for( t = 0; t < 4; t++ )
426         {
427             uint32_t j, k, l, m, n;
428
429             j = p_aes->pp_enc_keys[ i ][ t ];
430
431             k = (((j >> 7) & 0x01010101) * 27) ^ ((j & 0xff7f7f7f) << 1);
432             l = (((k >> 7) & 0x01010101) * 27) ^ ((k & 0xff7f7f7f) << 1);
433             m = (((l >> 7) & 0x01010101) * 27) ^ ((l & 0xff7f7f7f) << 1);
434
435             j ^= m;
436
437             n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
438
439             p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
440         }
441     }
442 }
443
444 /*****************************************************************************
445  * DecryptAES: decrypt an AES/Rijndael 128 bit block
446  *****************************************************************************/
447 static void DecryptAES( struct aes_s *p_aes,
448                         uint32_t *p_dest, const uint32_t *p_src )
449 {
450     uint32_t p_wtxt[ 4 ]; /* Working cyphertext */
451     uint32_t p_tmp[ 4 ];
452     unsigned int i_round, t;
453
454     for( t = 0; t < 4; t++ )
455     {
456         /* FIXME: are there any endianness issues here? */
457         p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
458     }
459
460     /* Rounds 0 - 8 */
461     for( i_round = 0; i_round < (AES_KEY_COUNT - 1); i_round++ )
462     {
463         for( t = 0; t < 4; t++ )
464         {
465             p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
466         }
467
468         for( t = 0; t < 4; t++ )
469         {
470             p_wtxt[ t ] = p_tmp[ t ]
471                     ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - i_round ][ t ];
472         }
473     }
474
475     /* Final round (9) */
476     for( t = 0; t < 4; t++ )
477     {
478         p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
479         p_dest[ t ] ^= p_aes->pp_dec_keys[ 0 ][ t ];
480     }
481 }
482
483 /*****************************************************************************
484  * InitMD5: initialise an MD5 message
485  *****************************************************************************
486  * The MD5 message-digest algorithm is described in RFC 1321
487  *****************************************************************************/
488 static void InitMD5( struct md5_s *p_md5 )
489 {
490     p_md5->p_digest[ 0 ] = 0x67452301;
491     p_md5->p_digest[ 1 ] = 0xefcdab89;
492     p_md5->p_digest[ 2 ] = 0x98badcfe;
493     p_md5->p_digest[ 3 ] = 0x10325476;
494
495     memset( p_md5->p_data, 0, 64 );
496     p_md5->i_bits = 0;
497 }
498
499 /*****************************************************************************
500  * AddMD5: add i_len bytes to an MD5 message
501  *****************************************************************************/
502 static void AddMD5( struct md5_s *p_md5, const uint8_t *p_src, uint32_t i_len )
503 {
504     unsigned int i_current; /* Current bytes in the spare buffer */
505     unsigned int i_offset = 0;
506
507     i_current = (p_md5->i_bits / 8) & 63;
508
509     p_md5->i_bits += 8 * i_len;
510
511     /* If we can complete our spare buffer to 64 bytes, do it and add the
512      * resulting buffer to the MD5 message */
513     if( i_len >= (64 - i_current) )
514     {
515         memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src,
516                 (64 - i_current) );
517         Digest( p_md5, p_md5->p_data );
518
519         i_offset += (64 - i_current);
520         i_len -= (64 - i_current);
521         i_current = 0;
522     }
523
524     /* Add as many entire 64 bytes blocks as we can to the MD5 message */
525     while( i_len >= 64 )
526     {
527         uint32_t p_tmp[ 16 ];
528         memcpy( p_tmp, p_src + i_offset, 64 );
529         Digest( p_md5, p_tmp );
530         i_offset += 64;
531         i_len -= 64;
532     }
533
534     /* Copy our remaining data to the message's spare buffer */
535     memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src + i_offset, i_len );
536 }
537
538 /*****************************************************************************
539  * EndMD5: finish an MD5 message
540  *****************************************************************************
541  * This function adds adequate padding to the end of the message, and appends
542  * the bit count so that we end at a block boundary.
543  *****************************************************************************/
544 static void EndMD5( struct md5_s *p_md5 )
545 {
546     unsigned int i_current;
547
548     i_current = (p_md5->i_bits / 8) & 63;
549
550     /* Append 0x80 to our buffer. No boundary check because the temporary
551      * buffer cannot be full, otherwise AddMD5 would have emptied it. */
552     ((uint8_t *)p_md5->p_data)[ i_current++ ] = 0x80;
553
554     /* If less than 8 bytes are available at the end of the block, complete
555      * this 64 bytes block with zeros and add it to the message. We'll add
556      * our length at the end of the next block. */
557     if( i_current > 56 )
558     {
559         memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (64 - i_current) );
560         Digest( p_md5, p_md5->p_data );
561         i_current = 0;
562     }
563
564     /* Fill the unused space in our last block with zeroes and put the
565      * message length at the end. */
566     memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (56 - i_current) );
567     p_md5->p_data[ 14 ] = p_md5->i_bits & 0xffffffff;
568     p_md5->p_data[ 15 ] = (p_md5->i_bits >> 32);
569     REVERSE( &p_md5->p_data[ 14 ], 2 );
570
571     Digest( p_md5, p_md5->p_data );
572 }
573
574 #define F1( x, y, z ) ((z) ^ ((x) & ((y) ^ (z))))
575 #define F2( x, y, z ) F1((z), (x), (y))
576 #define F3( x, y, z ) ((x) ^ (y) ^ (z))
577 #define F4( x, y, z ) ((y) ^ ((x) | ~(z)))
578
579 #define MD5_DO( f, w, x, y, z, data, s ) \
580     ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
581
582 /*****************************************************************************
583  * Digest: update the MD5 digest with 64 bytes of data
584  *****************************************************************************/
585 static void Digest( struct md5_s *p_md5, uint32_t *p_input )
586 {
587     uint32_t a, b, c, d;
588
589     REVERSE( p_input, 16 );
590
591     a = p_md5->p_digest[ 0 ];
592     b = p_md5->p_digest[ 1 ];
593     c = p_md5->p_digest[ 2 ];
594     d = p_md5->p_digest[ 3 ];
595
596     MD5_DO( F1, a, b, c, d, p_input[  0 ] + 0xd76aa478,  7 );
597     MD5_DO( F1, d, a, b, c, p_input[  1 ] + 0xe8c7b756, 12 );
598     MD5_DO( F1, c, d, a, b, p_input[  2 ] + 0x242070db, 17 );
599     MD5_DO( F1, b, c, d, a, p_input[  3 ] + 0xc1bdceee, 22 );
600     MD5_DO( F1, a, b, c, d, p_input[  4 ] + 0xf57c0faf,  7 );
601     MD5_DO( F1, d, a, b, c, p_input[  5 ] + 0x4787c62a, 12 );
602     MD5_DO( F1, c, d, a, b, p_input[  6 ] + 0xa8304613, 17 );
603     MD5_DO( F1, b, c, d, a, p_input[  7 ] + 0xfd469501, 22 );
604     MD5_DO( F1, a, b, c, d, p_input[  8 ] + 0x698098d8,  7 );
605     MD5_DO( F1, d, a, b, c, p_input[  9 ] + 0x8b44f7af, 12 );
606     MD5_DO( F1, c, d, a, b, p_input[ 10 ] + 0xffff5bb1, 17 );
607     MD5_DO( F1, b, c, d, a, p_input[ 11 ] + 0x895cd7be, 22 );
608     MD5_DO( F1, a, b, c, d, p_input[ 12 ] + 0x6b901122,  7 );
609     MD5_DO( F1, d, a, b, c, p_input[ 13 ] + 0xfd987193, 12 );
610     MD5_DO( F1, c, d, a, b, p_input[ 14 ] + 0xa679438e, 17 );
611     MD5_DO( F1, b, c, d, a, p_input[ 15 ] + 0x49b40821, 22 );
612
613     MD5_DO( F2, a, b, c, d, p_input[  1 ] + 0xf61e2562,  5 );
614     MD5_DO( F2, d, a, b, c, p_input[  6 ] + 0xc040b340,  9 );
615     MD5_DO( F2, c, d, a, b, p_input[ 11 ] + 0x265e5a51, 14 );
616     MD5_DO( F2, b, c, d, a, p_input[  0 ] + 0xe9b6c7aa, 20 );
617     MD5_DO( F2, a, b, c, d, p_input[  5 ] + 0xd62f105d,  5 );
618     MD5_DO( F2, d, a, b, c, p_input[ 10 ] + 0x02441453,  9 );
619     MD5_DO( F2, c, d, a, b, p_input[ 15 ] + 0xd8a1e681, 14 );
620     MD5_DO( F2, b, c, d, a, p_input[  4 ] + 0xe7d3fbc8, 20 );
621     MD5_DO( F2, a, b, c, d, p_input[  9 ] + 0x21e1cde6,  5 );
622     MD5_DO( F2, d, a, b, c, p_input[ 14 ] + 0xc33707d6,  9 );
623     MD5_DO( F2, c, d, a, b, p_input[  3 ] + 0xf4d50d87, 14 );
624     MD5_DO( F2, b, c, d, a, p_input[  8 ] + 0x455a14ed, 20 );
625     MD5_DO( F2, a, b, c, d, p_input[ 13 ] + 0xa9e3e905,  5 );
626     MD5_DO( F2, d, a, b, c, p_input[  2 ] + 0xfcefa3f8,  9 );
627     MD5_DO( F2, c, d, a, b, p_input[  7 ] + 0x676f02d9, 14 );
628     MD5_DO( F2, b, c, d, a, p_input[ 12 ] + 0x8d2a4c8a, 20 );
629
630     MD5_DO( F3, a, b, c, d, p_input[  5 ] + 0xfffa3942,  4 );
631     MD5_DO( F3, d, a, b, c, p_input[  8 ] + 0x8771f681, 11 );
632     MD5_DO( F3, c, d, a, b, p_input[ 11 ] + 0x6d9d6122, 16 );
633     MD5_DO( F3, b, c, d, a, p_input[ 14 ] + 0xfde5380c, 23 );
634     MD5_DO( F3, a, b, c, d, p_input[  1 ] + 0xa4beea44,  4 );
635     MD5_DO( F3, d, a, b, c, p_input[  4 ] + 0x4bdecfa9, 11 );
636     MD5_DO( F3, c, d, a, b, p_input[  7 ] + 0xf6bb4b60, 16 );
637     MD5_DO( F3, b, c, d, a, p_input[ 10 ] + 0xbebfbc70, 23 );
638     MD5_DO( F3, a, b, c, d, p_input[ 13 ] + 0x289b7ec6,  4 );
639     MD5_DO( F3, d, a, b, c, p_input[  0 ] + 0xeaa127fa, 11 );
640     MD5_DO( F3, c, d, a, b, p_input[  3 ] + 0xd4ef3085, 16 );
641     MD5_DO( F3, b, c, d, a, p_input[  6 ] + 0x04881d05, 23 );
642     MD5_DO( F3, a, b, c, d, p_input[  9 ] + 0xd9d4d039,  4 );
643     MD5_DO( F3, d, a, b, c, p_input[ 12 ] + 0xe6db99e5, 11 );
644     MD5_DO( F3, c, d, a, b, p_input[ 15 ] + 0x1fa27cf8, 16 );
645     MD5_DO( F3, b, c, d, a, p_input[  2 ] + 0xc4ac5665, 23 );
646
647     MD5_DO( F4, a, b, c, d, p_input[  0 ] + 0xf4292244,  6 );
648     MD5_DO( F4, d, a, b, c, p_input[  7 ] + 0x432aff97, 10 );
649     MD5_DO( F4, c, d, a, b, p_input[ 14 ] + 0xab9423a7, 15 );
650     MD5_DO( F4, b, c, d, a, p_input[  5 ] + 0xfc93a039, 21 );
651     MD5_DO( F4, a, b, c, d, p_input[ 12 ] + 0x655b59c3,  6 );
652     MD5_DO( F4, d, a, b, c, p_input[  3 ] + 0x8f0ccc92, 10 );
653     MD5_DO( F4, c, d, a, b, p_input[ 10 ] + 0xffeff47d, 15 );
654     MD5_DO( F4, b, c, d, a, p_input[  1 ] + 0x85845dd1, 21 );
655     MD5_DO( F4, a, b, c, d, p_input[  8 ] + 0x6fa87e4f,  6 );
656     MD5_DO( F4, d, a, b, c, p_input[ 15 ] + 0xfe2ce6e0, 10 );
657     MD5_DO( F4, c, d, a, b, p_input[  6 ] + 0xa3014314, 15 );
658     MD5_DO( F4, b, c, d, a, p_input[ 13 ] + 0x4e0811a1, 21 );
659     MD5_DO( F4, a, b, c, d, p_input[  4 ] + 0xf7537e82,  6 );
660     MD5_DO( F4, d, a, b, c, p_input[ 11 ] + 0xbd3af235, 10 );
661     MD5_DO( F4, c, d, a, b, p_input[  2 ] + 0x2ad7d2bb, 15 );
662     MD5_DO( F4, b, c, d, a, p_input[  9 ] + 0xeb86d391, 21 );
663
664     p_md5->p_digest[ 0 ] += a;
665     p_md5->p_digest[ 1 ] += b;
666     p_md5->p_digest[ 2 ] += c;
667     p_md5->p_digest[ 3 ] += d;
668 }
669
670 /*****************************************************************************
671  * InitShuffle: initialise a shuffle structure
672  *****************************************************************************
673  * This function initialises tables in the p_shuffle structure that will be
674  * used later by DoShuffle. The only external parameter is p_sys_key.
675  *****************************************************************************/
676 static void InitShuffle( struct shuffle_s *p_shuffle, uint32_t *p_sys_key,
677                          uint32_t i_version )
678 {
679     char p_secret1[] = "Tv!*";
680     static char const p_secret2[] = "v8rhvsaAvOKMFfUH%798=[;."
681                                     "f8677680a634ba87fnOIf)(*";
682     unsigned int i;
683
684     p_shuffle->i_version = i_version;
685
686     /* Fill p_commands using the key and a secret seed */
687     for( i = 0; i < 20; i++ )
688     {
689         struct md5_s md5;
690         int32_t i_hash;
691
692         InitMD5( &md5 );
693         AddMD5( &md5, (uint8_t *)p_sys_key, 16 );
694         AddMD5( &md5, (uint8_t *)p_secret1, 4 );
695         EndMD5( &md5 );
696
697         p_secret1[ 3 ]++;
698
699         REVERSE( md5.p_digest, 1 );
700         i_hash = ((int32_t)U32_AT(md5.p_digest)) % 1024;
701
702         p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
703     }
704
705     /* Fill p_bordel with completely meaningless initial values. */
706     for( i = 0; i < 4; i++ )
707     {
708         p_shuffle->p_bordel[ 4 * i ] = U32_AT(p_sys_key + i);
709         memcpy( p_shuffle->p_bordel + 4 * i + 1, p_secret2 + 12 * i, 12 );
710         REVERSE( p_shuffle->p_bordel + 4 * i + 1, 3 );
711     }
712 }
713
714 /*****************************************************************************
715  * DoShuffle: shuffle buffer
716  *****************************************************************************
717  * This is so ugly and uses so many MD5 checksums that it is most certainly
718  * one-way, though why it needs to be so complicated is beyond me.
719  *****************************************************************************/
720 static void DoShuffle( struct shuffle_s *p_shuffle,
721                        uint32_t *p_buffer, uint32_t i_size )
722 {
723     struct md5_s md5;
724     uint32_t p_big_bordel[ 16 ];
725     uint32_t *p_bordel = p_shuffle->p_bordel;
726     unsigned int i;
727
728     static uint32_t i_secret = 0;
729
730     static uint32_t p_secret1[] =
731     {
732         0xAAAAAAAA, 0x01757700, 0x00554580, 0x01724500, 0x00424580,
733         0x01427700, 0x00000080, 0xC1D59D01, 0x80144981, 0x815C8901,
734         0x80544981, 0x81D45D01, 0x00000080, 0x81A3BB03, 0x00A2AA82,
735         0x01A3BB03, 0x0022A282, 0x813BA202, 0x00000080, 0x6D575737,
736         0x4A5275A5, 0x6D525725, 0x4A5254A5, 0x6B725437, 0x00000080,
737         0xD5DDB938, 0x5455A092, 0x5D95A013, 0x4415A192, 0xC5DD393A,
738         0x00000080, 0x55555555
739     };
740
741     static char p_secret2[] =
742         "pbclevtug (p) Nccyr Pbzchgre, Vap.  Nyy Evtugf Erfreirq.";
743
744     if( i_secret == 0 )
745     {
746         REVERSE( p_secret1, sizeof(p_secret1)/sizeof(p_secret1[ 0 ]) );
747         for( ; p_secret2[ i_secret ] != '\0'; i_secret++ )
748         {
749 #define ROT13(c) (((c)>='A'&&(c)<='Z')?(((c)-'A'+13)%26)+'A':\
750                   ((c)>='a'&&(c)<='z')?(((c)-'a'+13)%26)+'a':c)
751             p_secret2[ i_secret ] = ROT13(p_secret2[ i_secret ]);
752         }
753         i_secret++; /* include zero terminator */
754     }
755
756     /* Using the MD5 hash of a memory block is probably not one-way enough
757      * for the iTunes people. This function randomises p_bordel depending on
758      * the values in p_commands to make things even more messy in p_bordel. */
759     for( i = 0; i < 20; i++ )
760     {
761         uint8_t i_command, i_index;
762
763         if( !p_shuffle->p_commands[ i ] )
764         {
765             continue;
766         }
767
768         i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
769         i_index = p_shuffle->p_commands[ i ] & 0xff;
770
771         switch( i_command )
772         {
773         case 0x3:
774             p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
775                                       + p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
776             break;
777         case 0x2:
778             p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
779             break;
780         case 0x1:
781             p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
782             break;
783         default:
784             p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
785             break;
786         }
787     }
788
789     if( p_shuffle->i_version == 0x01000300 )
790     {
791         DoExtShuffle( p_bordel );
792     }
793
794     /* Convert our newly randomised p_bordel to big endianness and take
795      * its MD5 hash. */
796     InitMD5( &md5 );
797     for( i = 0; i < 16; i++ )
798     {
799         p_big_bordel[ i ] = U32_AT(p_bordel + i);
800     }
801     AddMD5( &md5, (uint8_t *)p_big_bordel, 64 );
802     if( p_shuffle->i_version == 0x01000300 )
803     {
804         AddMD5( &md5, (uint8_t *)p_secret1, sizeof(p_secret1) );
805         AddMD5( &md5, (uint8_t *)p_secret2, i_secret );
806     }
807     EndMD5( &md5 );
808
809     /* XOR our buffer with the computed checksum */
810     for( i = 0; i < i_size; i++ )
811     {
812         p_buffer[ i ] ^= md5.p_digest[ i ];
813     }
814 }
815
816 /*****************************************************************************
817  * DoExtShuffle: extended shuffle
818  *****************************************************************************
819  * This is even uglier.
820  *****************************************************************************/
821 static void DoExtShuffle( uint32_t * p_bordel )
822 {
823     uint32_t i_ret;
824     struct shuffle_ext_s exs;
825     exs.p_bordel = p_bordel;
826
827     exs.i_tmp = FirstPass( p_bordel );
828
829     SecondPass( &exs );
830
831     i_ret = ThirdPass( p_bordel );
832
833     FourthPass( p_bordel, i_ret );
834
835     FifthPass( p_bordel );
836 }
837
838 static uint32_t FirstPass( uint32_t * p_bordel )
839 {
840     uint32_t i, j;
841     uint32_t i_cmd, i_ret;
842
843     i_ret = 5;
844     i_cmd = (p_bordel[ 5 ] + 10) >> 2;
845
846     if( p_bordel[ 5 ] > 0x7D0 )
847     {
848         i_cmd -= 0x305;
849     }
850
851     switch( i_cmd & 3 )
852     {
853         case 0:
854             p_bordel[ 5 ] += 5;
855             break;
856         case 1:
857             p_bordel[ 4 ] -= 1;
858             break;
859         case 2:
860             if( p_bordel[ 4 ] & 5 )
861             {
862                 p_bordel[ 1 ] ^= 0x4D;
863             }
864             /* no break */
865         case 3:
866             p_bordel[ 12 ] += 5;
867             break;
868     }
869
870     for( ; ; )
871     {
872         for( ; ; )
873         {
874             p_bordel[ 1 ] += 0x10000000;
875             p_bordel[ 3 ] += 0x12777;
876
877             if( (p_bordel[ 10 ] & 1) && i_ret )
878             {
879                 i_ret--;
880                 p_bordel[ 1 ] -= p_bordel[ 2 ];
881                 p_bordel[ 11 ] += p_bordel[ 12 ];
882                 break;
883             }
884
885             if( (p_bordel[ 1 ] + p_bordel[ 2 ]) >= 0x7D0 )
886             {
887                 i_cmd = ((p_bordel[ 3 ] ^ 0x567F) >> 2) & 7;
888
889                 switch( i_cmd )
890                 {
891                     case 0:
892                         for( i = 0; i < 3; i++ )
893                         {
894                             if( p_bordel[ i + 10 ] > 0x4E20 )
895                             {
896                                 p_bordel[ i + 1 ] += p_bordel[ i + 2 ];
897                             }
898                         }
899                         break;
900                     case 4:
901                         p_bordel[ 1 ] -= p_bordel[ 2 ];
902                         /* no break */
903                     case 3:
904                         p_bordel[ 11 ] += p_bordel[ 12 ];
905                         break;
906                     case 6:
907                         p_bordel[ 3 ] ^= p_bordel[ 4 ];
908                         /* no break */
909                     case 8:
910                         p_bordel[ 13 ] &= p_bordel[ 14 ];
911                         /* no break */
912                     case 1:
913                         p_bordel[ 0 ] |= p_bordel[ 1 ];
914                         if( i_ret )
915                         {
916                             return i_ret;
917                         }
918                         break;
919                 }
920
921                 break;
922             }
923         }
924
925         for( i = 0, i_cmd = 0; i < 16; i++ )
926         {
927             if( p_bordel[ i ] < p_bordel[ i_cmd ] )
928             {
929                 i_cmd = i;
930             }
931         }
932
933         if( i_ret && i_cmd != 5 )
934         {
935             i_ret--;
936         }
937         else
938         {
939             if( i_cmd == 5 )
940             {
941                 p_bordel[ 8 ] &= p_bordel[ 6 ] >> 1;
942                 p_bordel[ 3 ] <<= 1;
943             }
944
945             for( i = 0; i < 3; i++ )
946             {
947                 p_bordel[ 11 ] += 1;
948                 if( p_bordel[ 11 ] & 5 )
949                 {
950                     p_bordel[ 8 ] += p_bordel[ 9 ];
951                 }
952                 else if( i_ret )
953                 {
954                     i_ret--;
955                     i_cmd = 3;
956                     goto break2;
957                 }
958             }
959
960             i_cmd = (p_bordel[ 15 ] + 0x93) >> 3;
961             if( p_bordel[ 15 ] & 0x100 )
962             {
963                 i_cmd ^= 0xDEAD;
964             }
965         }
966
967         switch( i_cmd & 3 )
968         {
969             case 0:
970                 while( p_bordel[ 11 ] & 1 )
971                 {
972                     p_bordel[ 11 ] >>= 1;
973                     p_bordel[ 12 ] += 1;
974                 }
975                 /* no break */
976             case 2:
977                 p_bordel[ 14 ] -= 0x19FE;
978                 break;
979             case 3:
980                 if( i_ret )
981                 {
982                     i_ret--;
983                     p_bordel[ 5 ] += 5;
984                     continue;
985                 }
986                 break;
987         }
988
989         i_cmd = ((p_bordel[ 3 ] + p_bordel[ 4 ] + 10) >> 1) - p_bordel[ 4 ];
990         break;
991     }
992 break2:
993
994     switch( i_cmd & 3 )
995     {
996         case 0:
997             p_bordel[ 14 ] >>= 1;
998             break;
999         case 1:
1000             p_bordel[ 5 ] <<= 2;
1001             break;
1002         case 2:
1003             p_bordel[ 12 ] |= 5;
1004             break;
1005         case 3:
1006             p_bordel[ 15 ] &= 0x55;
1007             if( i_ret )
1008             {
1009                 p_bordel[ 2 ] &= 0xB62FC;
1010                 return i_ret;
1011             }
1012             break;
1013     }
1014
1015     for( i = 0, j = 0; i < 16; i++ )
1016     {
1017         if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) )
1018         {
1019             j = i;
1020         }
1021     }
1022
1023     if( j > 5 )
1024     {
1025         for( ; j < 15; j++ )
1026         {
1027             p_bordel[ j ] += p_bordel[ j + 1 ];
1028         }
1029     }
1030     else
1031     {
1032         p_bordel[ 2 ] &= 0xB62FC;
1033     }
1034
1035     return i_ret;
1036 }
1037
1038 static void SecondPass( struct shuffle_ext_s * p_exs )
1039 {
1040     uint32_t i;
1041
1042     p_exs->i_cmd = p_exs->p_bordel[ 6 ] + 0x194B;
1043     if( p_exs->p_bordel[ 6 ] > 0x2710 )
1044     {
1045         p_exs->i_cmd >>= 1;
1046     }
1047
1048     switch( p_exs->i_cmd & 3 )
1049     {
1050         case 1:
1051             p_exs->p_bordel[ 3 ] += 0x19FE;
1052             break;
1053         case 2:
1054             p_exs->p_bordel[ 7 ] -= p_exs->p_bordel[ 3 ] >> 2;
1055             /* no break */
1056         case 0:
1057             p_exs->p_bordel[ 5 ] ^= 0x248A;
1058             break;
1059     }
1060
1061     p_exs->i_jc = 5;
1062
1063     for( i = 0, p_exs->i_cmd = 0; i < 16; i++ )
1064     {
1065         if( p_exs->p_bordel[ i ] > p_exs->p_bordel[ p_exs->i_cmd ] )
1066         {
1067             p_exs->i_cmd = i;
1068         }
1069     }
1070
1071     switch( p_exs->i_cmd )
1072     {
1073         case 0:
1074             if( p_exs->p_bordel[ 1 ] < p_exs->p_bordel[ 8 ] )
1075             {
1076                 p_exs->p_bordel[ 5 ] += 1;
1077             }
1078             break;
1079         case 4:
1080             if( (p_exs->p_bordel[ 9 ] & 0x7777) == 0x3333 )
1081             {
1082                 p_exs->p_bordel[ 5 ] -= 1;
1083             }
1084             else
1085             {
1086                 p_exs->i_jc--;
1087                 if( p_exs->p_bordel[ 1 ] < p_exs->p_bordel[ 8 ] )
1088                 {
1089                     p_exs->p_bordel[ 5 ] += 1;
1090                 }
1091                 break;
1092             }
1093             /* no break */
1094         case 7:
1095             p_exs->p_bordel[ 2 ] -= 1;
1096             p_exs->p_bordel[ 1 ] -= p_exs->p_bordel[ 5 ];
1097             TinyShuffle1( p_exs->p_bordel );
1098             return;
1099         case 10:
1100             p_exs->p_bordel[ 4 ] -= 1;
1101             p_exs->p_bordel[ 5 ] += 1;
1102             p_exs->p_bordel[ 6 ] -= 1;
1103             p_exs->p_bordel[ 7 ] += 1;
1104             break;
1105         default:
1106             p_exs->p_bordel[ 15 ] ^= 0x18547EFF;
1107             break;
1108     }
1109
1110     BigShuffle1( p_exs );
1111 }
1112
1113 static void BigShuffle1( struct shuffle_ext_s * p_exs )
1114 {
1115     uint32_t i, j;
1116
1117     for( i = 0; i < 3; i++ )
1118     {
1119         p_exs->i_cmd = p_exs->p_bordel[ 12 ] + p_exs->p_bordel[ 13 ] + p_exs->p_bordel[ 6 ];
1120         p_exs->i_cmd -= (((uint32_t)(((uint64_t)p_exs->i_cmd * 0x0CCCCCCCD) >> 32)) >> 2) * 5;
1121
1122         if( p_exs->i_cmd > 4 )
1123         {
1124             break;
1125         }
1126
1127         switch( p_exs->i_cmd )
1128         {
1129             case 0:
1130                 p_exs->p_bordel[ 12 ] -= 1;
1131                 /* no break */
1132             case 1:
1133                 p_exs->p_bordel[ 12 ] -= 1;
1134                 p_exs->p_bordel[ 13 ] += 1;
1135                 break;
1136             case 2:
1137                 p_exs->p_bordel[ 13 ] += 4;
1138                 /* no break */
1139             case 3:
1140                 p_exs->p_bordel[ 12 ] -= 1;
1141                 break;
1142             case 4:
1143                 if( p_exs->i_jc )
1144                 {
1145                     p_exs->i_jc--;
1146                     p_exs->p_bordel[ 5 ] += 1;
1147                     p_exs->p_bordel[ 6 ] -= 1;
1148                     p_exs->p_bordel[ 7 ] += 1;
1149                     BigShuffle1( p_exs );
1150                     return;
1151                 }
1152                 break;
1153         }
1154     }
1155
1156     for( i = 0, j = 0; i < 16; i++ )
1157     {
1158         if( p_exs->p_bordel[ i ] < p_exs->p_bordel[ j ] )
1159         {
1160             j = i;
1161         }
1162     }
1163
1164     if( (p_exs->p_bordel[ j ] % (j + 1)) > 10 )
1165     {
1166         p_exs->p_bordel[ 1 ] -= 1;
1167
1168         p_exs->p_bordel[ 2 ] += 0x13;
1169         p_exs->p_bordel[ 12 ] += 1;
1170     }
1171
1172     BigShuffle2( p_exs );
1173 }
1174
1175 static void BigShuffle2( struct shuffle_ext_s * p_exs )
1176 {
1177     uint32_t i;
1178
1179     p_exs->p_bordel[ 2 ] &= 0x7F3F;
1180
1181     for( i = 0; i < 5; i++ )
1182     {
1183         p_exs->i_cmd = (p_exs->p_bordel[ 2 ] + 0xA) + i;
1184         p_exs->i_cmd -= (((uint32_t)(((uint64_t)p_exs->i_cmd * 0x0CCCCCCCD) >> 32)) >> 2) * 5;
1185
1186         if( p_exs->i_cmd > 4 )
1187         {
1188             continue;
1189         }
1190
1191         switch( p_exs->i_cmd )
1192         {
1193             case 0:
1194                 p_exs->p_bordel[ 12 ] &= p_exs->p_bordel[ 2 ];
1195                 /* no break */
1196             case 1:
1197                 p_exs->p_bordel[ 3 ] ^= p_exs->p_bordel[ 15 ];
1198                 break;
1199             case 2:
1200                 p_exs->p_bordel[ 15 ] += 0x576;
1201                 /* no break */
1202             case 3:
1203                 p_exs->p_bordel[ 7 ] -= 0x2D;
1204                 /* no break */
1205             case 4:
1206                 p_exs->p_bordel[ 1 ] <<= 1;
1207                 break;
1208         }
1209     }
1210
1211     p_exs->i_cmd = (p_exs->p_bordel[ 2 ] * 2) + 15;
1212     p_exs->i_cmd -= (((uint32_t)(((uint64_t)p_exs->i_cmd * 0x0CCCCCCCD) >> 32)) >> 2) * 5;
1213
1214     switch( p_exs->i_cmd )
1215     {
1216         case 0:
1217             if( ( p_exs->p_bordel[ 3 ] + p_exs->i_tmp ) <=
1218                 ( p_exs->p_bordel[ 1 ] + p_exs->p_bordel[ 15 ] ) )
1219             {
1220                 p_exs->p_bordel[ 3 ] += 1;
1221             }
1222             break;
1223         case 3:
1224             p_exs->p_bordel[ 5 ] >>= 2;
1225             break;
1226         case 4:
1227             p_exs->p_bordel[ 10 ] -= 0x13;
1228             break;
1229     }
1230
1231     p_exs->i_cmd = ((p_exs->p_bordel[ 2 ] * 2) + 10) >> 1;
1232     if( p_exs->p_bordel[ 2 ] & 1 )
1233     {
1234         if( p_exs->i_jc )
1235         {
1236             p_exs->i_jc--;
1237             p_exs->p_bordel[ 2 ] += 0x13;
1238             p_exs->p_bordel[ 12 ] += 1;
1239             BigShuffle2( p_exs );
1240             return;
1241         }
1242     }
1243
1244     p_exs->i_cmd -= p_exs->p_bordel[ 2 ];
1245     p_exs->i_cmd -= (((uint32_t)(((uint64_t)p_exs->i_cmd * 0x0CCCCCCCD) >> 32)) >> 3) * 10;
1246
1247     switch( p_exs->i_cmd )
1248     {
1249         case 0:
1250             for( i = 0; i < 5; i++ )
1251             {
1252                 if( ( p_exs->p_bordel[ 1 ] & p_exs->p_bordel[ 2 ] ) >
1253                     ( p_exs->p_bordel[ 7 ] & p_exs->p_bordel[ 12 ] ) )
1254                 {
1255                     p_exs->p_bordel[ 2 ] += 1;
1256                     p_exs->p_bordel[ 7 ] ^= p_exs->p_bordel[ 2 ];
1257                 }
1258             }
1259         case 1:
1260             p_exs->p_bordel[ 3 ] -= 1;
1261             p_exs->p_bordel[ 4 ] |= 0x400000;
1262             break;
1263         case 2:
1264             if( p_exs->p_bordel[ 13 ] >= p_exs->p_bordel[ 3 ] )
1265             {
1266                 if( p_exs->i_jc )
1267                 {
1268                     p_exs->i_jc--;
1269                     p_exs->p_bordel[ 5 ] += 1;
1270                     p_exs->p_bordel[ 6 ] -= 1;
1271                     p_exs->p_bordel[ 7 ] += 1;
1272                     BigShuffle1( p_exs );
1273                 }
1274                 return;
1275             }
1276             else
1277             {
1278                 p_exs->p_bordel[ 5 ] += 3;
1279             }
1280             break;
1281         case 3:
1282             p_exs->p_bordel[ 1 ] ^= (p_exs->p_bordel[ 5 ] + p_exs->p_bordel[ 15 ]);
1283             break;
1284         case 4:
1285             p_exs->p_bordel[ 14 ] += 1;
1286             break;
1287         case 5:
1288             p_exs->p_bordel[ 2 ] &= 0x10076000;
1289             break;
1290         case 6:
1291             p_exs->p_bordel[ 1 ] -= p_exs->p_bordel[ 5 ];
1292             /* no break */
1293         case 7:
1294             TinyShuffle1( p_exs->p_bordel );
1295             break;
1296         case 8:
1297             p_exs->p_bordel[ 7 ] ^= ((p_exs->p_bordel[ 1 ] + p_exs->p_bordel[ 5 ]) - p_exs->p_bordel[ 8 ]);
1298             break;
1299         case 9:
1300             if( (p_exs->p_bordel[ 1 ] ^ p_exs->p_bordel[ 10 ]) > 0x6000 )
1301             {
1302                 p_exs->p_bordel[ 11 ] += 1;
1303             }
1304             break;
1305     }
1306 }
1307
1308 static uint32_t ThirdPass( uint32_t * p_bordel )
1309 {
1310     uint32_t i_cmd, i_ret = 5;
1311
1312     i_cmd = ((p_bordel[ 7 ] + p_bordel[ 14 ] + 10) >> 1) - p_bordel[ 14 ];
1313     i_cmd -= (((uint32_t)(((uint64_t)i_cmd * 0x0CCCCCCCD) >> 32)) >> 3) * 10;
1314
1315     switch( i_cmd )
1316     {
1317         case 0:
1318             p_bordel[ 1 ] <<= 1;
1319             p_bordel[ 2 ] <<= 2;
1320             p_bordel[ 3 ] <<= 3;
1321             break;
1322         case 6:
1323             p_bordel[ i_cmd + 3 ] &= 0x5EDE36B;
1324             /* no break */
1325         case 2:
1326             while( i_cmd )
1327             {
1328                 i_cmd -= 1;
1329                 p_bordel[ i_cmd ] += p_bordel[ i_cmd + 3 ];
1330             }
1331             i_ret--;
1332             TinyShuffle2( p_bordel );
1333             return i_ret;
1334         case 3:
1335             if( (p_bordel[ 11 ] & p_bordel[ 2 ]) > 0x211B )
1336             {
1337                 p_bordel[ 6 ] += 1;
1338             }
1339             break;
1340         case 4:
1341             p_bordel[ 7 ] += 1;
1342             /* no break */
1343         case 5:
1344             p_bordel[ 9 ] ^= p_bordel[ 2 ];
1345             break;
1346         case 7:
1347             p_bordel[ 2 ] ^= (p_bordel[ 1 ] & p_bordel[ 13 ]);
1348             break;
1349         case 8:
1350             p_bordel[ 0 ] -= p_bordel[ 11 ] & p_bordel[ 15 ];
1351             i_ret--;
1352             return i_ret;
1353         case 9:
1354             p_bordel[ 6 ] >>= (p_bordel[ 14 ] & 3);
1355             break;
1356     }
1357
1358     SWAP( p_bordel[ 0 ], p_bordel[ 10 ] );
1359
1360     TinyShuffle2( p_bordel );
1361
1362     return i_ret;
1363 }
1364
1365 static void FourthPass( uint32_t * p_bordel, uint32_t i_jc )
1366 {
1367     uint32_t i, j;
1368     uint32_t i_cmd;
1369
1370     i = (((p_bordel[ 9 ] + p_bordel[ 15 ] + 12) >> 2) - p_bordel[ 4 ]) & 7;
1371
1372     while( i-- )
1373     {
1374         SWAP( p_bordel[ i ], p_bordel[ i + 3 ] );
1375     }
1376
1377     SWAP( p_bordel[ 10 ], p_bordel[ 1 ] );
1378
1379     i_cmd = p_bordel[ 5 ];
1380     i_cmd -= (((uint32_t)(((uint64_t)i_cmd * 0x0CCCCCCCD) >> 32)) >> 2) * 5;
1381
1382     switch( i_cmd )
1383     {
1384         case 0:
1385             p_bordel[ 0 ] += 1;
1386             break;
1387         case 2:
1388             p_bordel[ 11 ] ^= (p_bordel[ 3 ] + p_bordel[ 6 ] + p_bordel[ 8 ]);
1389             break;
1390         case 3:
1391             for( i = 4; i < 15; i++ )
1392             {
1393                 if( p_bordel[ i ] & 5 )
1394                 {
1395                     break;
1396                 }
1397
1398                 SWAP( p_bordel[ i ], p_bordel[ 15 - i ] );
1399             }
1400             break;
1401         case 4:
1402             if( i_jc )
1403             {
1404                 p_bordel[ 12 ] -= 1;
1405                 p_bordel[ 13 ] += 1;
1406                 p_bordel[ 2 ] -= 0x64;
1407                 p_bordel[ 3 ] += 0x64;
1408                 return;
1409             }
1410             break;
1411     }
1412
1413     for( i = 0, j = 0; i < 16; i++ )
1414     {
1415         if( p_bordel[ i ] > p_bordel[ j ] )
1416         {
1417             j = i;
1418         }
1419     }
1420
1421     i_cmd = p_bordel[ j ];
1422     i_cmd -= (((uint32_t)(((uint64_t)i_cmd * 0x51EB851F) >> 32)) >> 5) * 0x64;
1423
1424     switch( i_cmd )
1425     {
1426         case 0x0:
1427             SWAP( p_bordel[ j ], p_bordel[ 0 ] );
1428             break;
1429         case 0x8:
1430             p_bordel[ 1 ] >>= 1;
1431             p_bordel[ 2 ] <<= 1;
1432             p_bordel[ 14 ] >>= 3;
1433             p_bordel[ 15 ] <<= 4;
1434             break;
1435         case 0x39:
1436             p_bordel[ j ] += p_bordel[ 13 ];
1437             break;
1438         case 0x4c:
1439             if( i_jc )
1440             {
1441                 p_bordel[ 1 ] += 0x20E;
1442                 p_bordel[ 5 ] += 0x223D;
1443                 p_bordel[ 13 ] -= 0x576;
1444                 p_bordel[ 15 ] += 0x576;
1445             }
1446             break;
1447         case 0x5b:
1448             p_bordel[ 2 ] -= 0x64;
1449             p_bordel[ 3 ] += 0x64;
1450             p_bordel[ 12 ] -= 1;
1451             p_bordel[ 13 ] += 1;
1452             break;
1453         case 0x63:
1454             p_bordel[ 0 ] += 1;
1455             p_bordel[ j ] += p_bordel[ 13 ];
1456             break;
1457     }
1458 }
1459
1460 static void FifthPass( uint32_t * p_bordel )
1461 {
1462     uint32_t i;
1463     uint32_t i_cmd;
1464
1465     i = (p_bordel[ 0 ] & p_bordel[ 6 ]) & 0xF;
1466
1467     i_cmd = p_bordel[ i ];
1468     i_cmd -= ((((uint32_t)(((uint64_t)i_cmd * 0x10624DD3) >> 32)) >> 6) * 0x3E8);
1469
1470     switch( i_cmd )
1471     {
1472         case 0x7:
1473             if( (p_bordel[ i ] & 0x777) > (p_bordel[ 7 ] & 0x5555) )
1474             {
1475                 p_bordel[ i ] ^= p_bordel[ 5 ] & p_bordel[ 3 ];
1476             }
1477             break;
1478         case 0x13:
1479             p_bordel[ 15 ] &= 0x5555;
1480             break;
1481         case 0x5d:
1482             p_bordel[ i ] ^= p_bordel[ 15 ];
1483             break;
1484         case 0x64:
1485             SWAP( p_bordel[ 0 ], p_bordel[ 1 ] );
1486             SWAP( p_bordel[ 1 ], p_bordel[ 7 ] );
1487             SWAP( p_bordel[ 4 ], p_bordel[ 9 ] );
1488             SWAP( p_bordel[ 8 ], p_bordel[ 5 ] );
1489             SWAP( p_bordel[ 6 ], p_bordel[ 1 ] );
1490             SWAP( p_bordel[ 3 ], p_bordel[ 0 ] );
1491             SWAP( p_bordel[ 13 ], p_bordel[ 14 ] );
1492             break;
1493         case 0x149:
1494             p_bordel[ i ] += p_bordel[ 1 ] ^ 0x80080011;
1495             p_bordel[ i ] += p_bordel[ 2 ] ^ 0xBEEFDEAD;
1496             p_bordel[ i ] += p_bordel[ 3 ] ^ 0x8765F444;
1497             p_bordel[ i ] += p_bordel[ 4 ] ^ 0x78145326;
1498             break;
1499         case 0x237:
1500             p_bordel[ 12 ] -= p_bordel[ i ];
1501             p_bordel[ 13 ] += p_bordel[ i ];
1502             break;
1503         case 0x264:
1504             p_bordel[ i ] += p_bordel[ 1 ];
1505             p_bordel[ i ] -= p_bordel[ 7 ];
1506             p_bordel[ i ] -= p_bordel[ 8 ];
1507             p_bordel[ i ] += p_bordel[ 9 ];
1508             p_bordel[ i ] += p_bordel[ 13 ];
1509             break;
1510         case 0x2f2:
1511             i = __MIN( i, 12 );
1512             p_bordel[ i + 1 ] >>= 1;
1513             p_bordel[ i + 2 ] <<= 4;
1514             p_bordel[ i + 3 ] >>= 3;
1515             break;
1516         case 0x309:
1517             p_bordel[ 1 ] += 0x20E;
1518             p_bordel[ 5 ] += 0x223D;
1519             p_bordel[ 13 ] -= 0x576;
1520             p_bordel[ 15 ] += 0x576;
1521             break;
1522         case 0x3d5:
1523             if( (p_bordel[ i ] ^ 0x8765F441) < 0x2710 )
1524             {
1525                 SWAP( p_bordel[ 0 ], p_bordel[ 1 ] );
1526             }
1527             else
1528             {
1529                 SWAP( p_bordel[ 1 ], p_bordel[ 11 ] );
1530             }
1531             break;
1532     }
1533 }
1534
1535 static void TinyShuffle1( uint32_t * p_bordel )
1536 {
1537     uint32_t i;
1538
1539     for( i = 0; i < 3; i++ )
1540     {
1541         switch( p_bordel[ 1 ] & 3 )
1542         {
1543             case 0:
1544                 p_bordel[ 1 ] += 1;
1545                 /* no break */
1546             case 1:
1547                 p_bordel[ 3 ] -= 8;
1548                 break;
1549             case 2:
1550                 p_bordel[ 13 ] &= 0xFEFEFEF7;
1551                 break;
1552             case 3:
1553                 p_bordel[ 8 ] |= 0x80080011;
1554                 break;
1555         }
1556     }
1557 }
1558
1559 static void TinyShuffle2( uint32_t * p_bordel )
1560 {
1561     uint32_t i;
1562
1563     for( i = 0; i < 8; i++ )
1564     {
1565         if( p_bordel[ 3 ] & 0x7514 )
1566         {
1567             SWAP( p_bordel[ i ], p_bordel[ i + 5 ] );
1568         }
1569         else
1570         {
1571             SWAP( p_bordel[ i ], p_bordel[ i + 7 ] );
1572         }
1573     }
1574 }
1575
1576 /*****************************************************************************
1577  * GetSystemKey: get the system key
1578  *****************************************************************************
1579  * Compute the system key from various system information, see HashSystemInfo.
1580  *****************************************************************************/
1581 static int GetSystemKey( uint32_t *p_sys_key, vlc_bool_t b_ipod )
1582 {
1583     static char const p_secret1[ 8 ] = "YuaFlafu";
1584     static char const p_secret2[ 8 ] = "zPif98ga";
1585     struct md5_s md5;
1586     int64_t i_ipod_id;
1587     uint32_t p_system_hash[ 4 ];
1588
1589     /* Compute the MD5 hash of our system info */
1590     if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) ||
1591         (  b_ipod && GetiPodID( &i_ipod_id ) ) )
1592     {
1593         return -1;
1594     }
1595
1596     /* Combine our system info hash with additional secret data. The resulting
1597      * MD5 hash will be our system key. */
1598     InitMD5( &md5 );
1599     AddMD5( &md5, p_secret1, 8 );
1600
1601     if( !b_ipod )
1602     {
1603         AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
1604         AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
1605         AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
1606         AddMD5( &md5, p_secret2, 8 );
1607     }
1608     else
1609     {
1610         i_ipod_id = U64_AT(&i_ipod_id);
1611         AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1612         AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1613         AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1614     }
1615
1616     EndMD5( &md5 );
1617
1618     memcpy( p_sys_key, md5.p_digest, 16 );
1619
1620     return 0;
1621 }
1622
1623 #ifdef WIN32
1624 #   define DRMS_DIRNAME "drms"
1625 #else
1626 #   define DRMS_DIRNAME ".drms"
1627 #endif
1628
1629 /*****************************************************************************
1630  * WriteUserKey: write the user key to hard disk
1631  *****************************************************************************
1632  * Write the user key to the hard disk so that it can be reused later or used
1633  * on operating systems other than Win32.
1634  *****************************************************************************/
1635 static int WriteUserKey( void *_p_drms, uint32_t *p_user_key )
1636 {
1637     struct drms_s *p_drms = (struct drms_s *)_p_drms;
1638     FILE *file;
1639     int i_ret = -1;
1640     char psz_path[ PATH_MAX ];
1641
1642     snprintf( psz_path, PATH_MAX - 1,
1643               "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
1644
1645 #if defined( HAVE_ERRNO_H )
1646 #   if defined( WIN32 )
1647     if( !mkdir( psz_path ) || errno == EEXIST )
1648 #   else
1649     if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
1650 #   endif
1651 #else
1652     if( !mkdir( psz_path ) )
1653 #endif
1654     {
1655         snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d",
1656                   p_drms->psz_homedir, p_drms->i_user, p_drms->i_key );
1657
1658         file = fopen( psz_path, "wb" );
1659         if( file != NULL )
1660         {
1661             i_ret = fwrite( p_user_key, sizeof(uint32_t),
1662                             4, file ) == 4 ? 0 : -1;
1663             fclose( file );
1664         }
1665     }
1666
1667     return i_ret;
1668 }
1669
1670 /*****************************************************************************
1671  * ReadUserKey: read the user key from hard disk
1672  *****************************************************************************
1673  * Retrieve the user key from the hard disk if available.
1674  *****************************************************************************/
1675 static int ReadUserKey( void *_p_drms, uint32_t *p_user_key )
1676 {
1677     struct drms_s *p_drms = (struct drms_s *)_p_drms;
1678     FILE *file;
1679     int i_ret = -1;
1680     char psz_path[ PATH_MAX ];
1681
1682     snprintf( psz_path, PATH_MAX - 1,
1683               "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir,
1684               p_drms->i_user, p_drms->i_key );
1685
1686     file = fopen( psz_path, "rb" );
1687     if( file != NULL )
1688     {
1689         i_ret = fread( p_user_key, sizeof(uint32_t),
1690                        4, file ) == 4 ? 0 : -1;
1691         fclose( file );
1692     }
1693
1694     return i_ret;
1695 }
1696
1697 /*****************************************************************************
1698  * GetUserKey: get the user key
1699  *****************************************************************************
1700  * Retrieve the user key from the hard disk if available, otherwise generate
1701  * it from the system key. If the key could be successfully generated, write
1702  * it to the hard disk for future use.
1703  *****************************************************************************/
1704 static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
1705 {
1706     static char const p_secret[] = "mUfnpognadfgf873";
1707     struct drms_s *p_drms = (struct drms_s *)_p_drms;
1708     struct aes_s aes;
1709     struct shuffle_s shuffle;
1710     uint32_t i, y;
1711     uint32_t *p_sci_data;
1712     uint32_t i_user, i_key;
1713     uint32_t p_sys_key[ 4 ];
1714     uint32_t i_sci_size, i_blocks, i_remaining;
1715     uint32_t *p_sci0, *p_sci1, *p_buffer;
1716     uint32_t p_sci_key[ 4 ];
1717     char *psz_ipod;
1718     int i_ret = -1;
1719
1720     if( !ReadUserKey( p_drms, p_user_key ) )
1721     {
1722         REVERSE( p_user_key, 4 );
1723         return 0;
1724     }
1725
1726     psz_ipod = getenv( "IPOD" );
1727
1728     if( GetSystemKey( p_sys_key, psz_ipod ? VLC_TRUE : VLC_FALSE ) )
1729     {
1730         return -1;
1731     }
1732
1733     if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
1734     {
1735         return -1;
1736     }
1737
1738     /* Phase 1: unscramble the SCI data using the system key and shuffle
1739      *          it using DoShuffle(). */
1740
1741     /* Skip the first 4 bytes (some sort of header). Decrypt the rest. */
1742     i_blocks = (i_sci_size - 4) / 16;
1743     i_remaining = (i_sci_size - 4) - (i_blocks * 16);
1744     p_buffer = p_sci_data + 1;
1745
1746     /* Decrypt and shuffle our data at the same time */
1747     InitAES( &aes, p_sys_key );
1748     REVERSE( p_sys_key, 4 );
1749     InitShuffle( &shuffle, p_sys_key, p_sci_data[ 0 ] );
1750
1751     memcpy( p_sci_key, p_secret, 16 );
1752     REVERSE( p_sci_key, 4 );
1753
1754     while( i_blocks-- )
1755     {
1756         uint32_t p_tmp[ 4 ];
1757
1758         REVERSE( p_buffer, 4 );
1759         DecryptAES( &aes, p_tmp, p_buffer );
1760         BlockXOR( p_tmp, p_sci_key, p_tmp );
1761
1762         /* Use the previous scrambled data as the key for next block */
1763         memcpy( p_sci_key, p_buffer, 16 );
1764
1765         /* Shuffle the decrypted data using a custom routine */
1766         DoShuffle( &shuffle, p_tmp, 4 );
1767
1768         /* Copy this block back to p_buffer */
1769         memcpy( p_buffer, p_tmp, 16 );
1770
1771         p_buffer += 4;
1772     }
1773
1774     if( i_remaining >= 4 )
1775     {
1776         i_remaining /= 4;
1777         REVERSE( p_buffer, i_remaining );
1778         DoShuffle( &shuffle, p_buffer, i_remaining );
1779     }
1780
1781     /* Phase 2: look for the user key in the generated data. I must admit I
1782      *          do not understand what is going on here, because it almost
1783      *          looks like we are browsing data that makes sense, even though
1784      *          the DoShuffle() part made it completely meaningless. */
1785
1786     y = 0;
1787     REVERSE( p_sci_data + 5, 1 );
1788     i = U32_AT( p_sci_data + 5 );
1789     i_sci_size -= 22 * sizeof(uint32_t);
1790     p_sci1 = p_sci_data + 22;
1791     p_sci0 = NULL;
1792
1793     while( i_sci_size >= 20 && i > 0 )
1794     {
1795         if( p_sci0 == NULL )
1796         {
1797             i_sci_size -= 18 * sizeof(uint32_t);
1798             if( i_sci_size < 20 )
1799             {
1800                 break;
1801             }
1802
1803             p_sci0 = p_sci1;
1804             REVERSE( p_sci1 + 17, 1 );
1805             y = U32_AT( p_sci1 + 17 );
1806             p_sci1 += 18;
1807         }
1808
1809         if( !y )
1810         {
1811             i--;
1812             p_sci0 = NULL;
1813             continue;
1814         }
1815
1816         i_user = U32_AT( p_sci0 );
1817         i_key = U32_AT( p_sci1 );
1818         REVERSE( &i_user, 1 );
1819         REVERSE( &i_key, 1 );
1820         if( i_user == p_drms->i_user && ( ( i_key == p_drms->i_key ) ||
1821             ( !p_drms->i_key && ( p_sci1 == (p_sci0 + 18) ) ) ) )
1822         {
1823             memcpy( p_user_key, p_sci1 + 1, 16 );
1824             REVERSE( p_sci1 + 1, 4 );
1825             WriteUserKey( p_drms, p_sci1 + 1 );
1826             i_ret = 0;
1827             break;
1828         }
1829
1830         y--;
1831         p_sci1 += 5;
1832         i_sci_size -= 5 * sizeof(uint32_t);
1833     }
1834
1835     free( p_sci_data );
1836
1837     return i_ret;
1838 }
1839
1840 /*****************************************************************************
1841  * GetSCIData: get SCI data from "SC Info.sidb"
1842  *****************************************************************************
1843  * Read SCI data from "\Apple Computer\iTunes\SC Info\SC Info.sidb"
1844  *****************************************************************************/
1845 static int GetSCIData( char *psz_ipod, uint32_t **pp_sci,
1846                        uint32_t *pi_sci_size )
1847 {
1848     FILE *file;
1849     char *psz_path = NULL;
1850     char p_tmp[ PATH_MAX ];
1851     int i_ret = -1;
1852
1853     if( psz_ipod == NULL )
1854     {
1855 #ifdef WIN32
1856         char *p_filename = "\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb";
1857         typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
1858                                                    LPSTR );
1859         HINSTANCE shfolder_dll = NULL;
1860         SHGETFOLDERPATH dSHGetFolderPath = NULL;
1861
1862         if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
1863         {
1864             dSHGetFolderPath =
1865                 (SHGETFOLDERPATH)GetProcAddress( shfolder_dll,
1866                                                  _T("SHGetFolderPathA") );
1867         }
1868
1869         if( dSHGetFolderPath != NULL &&
1870             SUCCEEDED( dSHGetFolderPath( NULL, CSIDL_COMMON_APPDATA,
1871                                          NULL, 0, p_tmp ) ) )
1872         {
1873             strncat( p_tmp, p_filename, min( strlen( p_filename ),
1874                      (sizeof(p_tmp)/sizeof(p_tmp[0]) - 1) -
1875                      strlen( p_tmp ) ) );
1876             psz_path = p_tmp;
1877         }
1878
1879         if( shfolder_dll != NULL )
1880         {
1881             FreeLibrary( shfolder_dll );
1882         }
1883 #endif
1884     }
1885     else
1886     {
1887 #define ISCINFO "iSCInfo"
1888         if( strstr( psz_ipod, ISCINFO ) == NULL )
1889         {
1890             snprintf( p_tmp, sizeof(p_tmp)/sizeof(p_tmp[0]) - 1,
1891                       "%s/iPod_Control/iTunes/" ISCINFO "2", psz_ipod );
1892             psz_path = p_tmp;
1893         }
1894         else
1895         {
1896             psz_path = psz_ipod;
1897         }
1898     }
1899
1900     if( psz_path == NULL )
1901     {
1902         return -1;
1903     }
1904
1905     file = fopen( psz_path, "rb" );
1906     if( file != NULL )
1907     {
1908         struct stat st;
1909
1910         if( !fstat( fileno( file ), &st ) )
1911         {
1912             *pp_sci = malloc( st.st_size );
1913             if( *pp_sci != NULL )
1914             {
1915                 if( fread( *pp_sci, 1, st.st_size,
1916                            file ) == (size_t)st.st_size )
1917                 {
1918                     *pi_sci_size = st.st_size;
1919                     i_ret = 0;
1920                 }
1921                 else
1922                 {
1923                     free( (void *)*pp_sci );
1924                     *pp_sci = NULL;
1925                 }
1926             }
1927         }
1928
1929         fclose( file );
1930     }
1931
1932     return i_ret;
1933 }
1934
1935 /*****************************************************************************
1936  * HashSystemInfo: hash system information
1937  *****************************************************************************
1938  * This function computes the MD5 hash of the C: hard drive serial number,
1939  * BIOS version, CPU type and Windows version.
1940  *****************************************************************************/
1941 static int HashSystemInfo( uint32_t *p_system_hash )
1942 {
1943     struct md5_s md5;
1944     int i_ret = 0;
1945
1946 #ifdef WIN32
1947     HKEY i_key;
1948     unsigned int i;
1949     DWORD i_size;
1950     DWORD i_serial;
1951     LPBYTE p_reg_buf;
1952
1953     static LPCTSTR p_reg_keys[ 3 ][ 2 ] =
1954     {
1955         {
1956             _T("HARDWARE\\DESCRIPTION\\System"),
1957             _T("SystemBiosVersion")
1958         },
1959
1960         {
1961             _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
1962             _T("ProcessorNameString")
1963         },
1964
1965         {
1966             _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
1967             _T("ProductId")
1968         }
1969     };
1970
1971     InitMD5( &md5 );
1972
1973     AddMD5( &md5, "cache-control", 13 );
1974     AddMD5( &md5, "Ethernet", 8 );
1975
1976     GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
1977                           NULL, NULL, NULL, 0 );
1978     AddMD5( &md5, (uint8_t *)&i_serial, 4 );
1979
1980     for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
1981     {
1982         if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
1983                           0, KEY_READ, &i_key ) != ERROR_SUCCESS )
1984         {
1985             continue;
1986         }
1987
1988         if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1989                              NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
1990         {
1991             RegCloseKey( i_key );
1992             continue;
1993         }
1994
1995         p_reg_buf = malloc( i_size );
1996
1997         if( p_reg_buf != NULL )
1998         {
1999             if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
2000                                  NULL, NULL, p_reg_buf,
2001                                  &i_size ) == ERROR_SUCCESS )
2002             {
2003                 AddMD5( &md5, (uint8_t *)p_reg_buf, i_size );
2004             }
2005
2006             free( p_reg_buf );
2007         }
2008
2009         RegCloseKey( i_key );
2010     }
2011
2012 #else
2013     InitMD5( &md5 );
2014     i_ret = -1;
2015 #endif
2016
2017     EndMD5( &md5 );
2018     memcpy( p_system_hash, md5.p_digest, 16 );
2019
2020     return i_ret;
2021 }
2022
2023 /*****************************************************************************
2024  * GetiPodID: Get iPod ID
2025  *****************************************************************************
2026  * This function gets the iPod ID.
2027  *****************************************************************************/
2028 static int GetiPodID( int64_t *p_ipod_id )
2029 {
2030     int i_ret = -1;
2031
2032 #define PROD_NAME   "iPod"
2033 #define VENDOR_NAME "Apple Computer, Inc."
2034
2035     char *psz_ipod_id = getenv( "IPODID" );
2036     if( psz_ipod_id != NULL )
2037     {
2038         *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
2039         return 0;
2040     }
2041
2042 #ifdef SYS_DARWIN
2043     CFTypeRef value;
2044     mach_port_t port;
2045     io_object_t device;
2046     io_iterator_t iterator;
2047     CFMutableDictionaryRef matching_dic;
2048
2049     if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
2050     {
2051         if( ( matching_dic = IOServiceMatching( "IOFireWireUnit" ) ) != NULL )
2052         {
2053             CFDictionarySetValue( matching_dic,
2054                                   CFSTR("FireWire Vendor Name"),
2055                                   CFSTR(VENDOR_NAME) );
2056             CFDictionarySetValue( matching_dic,
2057                                   CFSTR("FireWire Product Name"),
2058                                   CFSTR(PROD_NAME) );
2059
2060             if( IOServiceGetMatchingServices( port, matching_dic,
2061                                               &iterator ) == KERN_SUCCESS )
2062             {
2063                 while( ( device = IOIteratorNext( iterator ) ) != NULL )
2064                 {
2065                     value = IORegistryEntryCreateCFProperty( device,
2066                         CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );
2067
2068                     if( value != NULL )
2069                     {
2070                         if( CFGetTypeID( value ) == CFNumberGetTypeID() )
2071                         {
2072                             int64_t i_ipod_id;
2073                             CFNumberGetValue( (CFNumberRef)value,
2074                                               kCFNumberLongLongType,
2075                                               &i_ipod_id );
2076                             *p_ipod_id = i_ipod_id;
2077                             i_ret = 0;
2078                         }
2079
2080                         CFRelease( value );
2081                     }
2082
2083                     IOObjectRelease( device );
2084
2085                     if( !i_ret ) break;
2086                 }
2087
2088                 IOObjectRelease( iterator );
2089             }
2090         }
2091
2092         mach_port_deallocate( mach_task_self(), port );
2093     }
2094
2095 #elif HAVE_SYSFS_LIBSYSFS_H
2096     struct sysfs_bus *bus = NULL;
2097     struct dlist *devlist = NULL;
2098     struct dlist *attributes = NULL;
2099     struct sysfs_device *curdev = NULL;
2100     struct sysfs_attribute *curattr = NULL;
2101
2102     bus = sysfs_open_bus( "ieee1394" );
2103     if( bus != NULL )
2104     {
2105         devlist = sysfs_get_bus_devices( bus );
2106         if( devlist != NULL )
2107         {
2108             dlist_for_each_data( devlist, curdev, struct sysfs_device )
2109             {
2110                 attributes = sysfs_get_device_attributes( curdev );
2111                 if( attributes != NULL )
2112                 {
2113                     dlist_for_each_data( attributes, curattr,
2114                                          struct sysfs_attribute )
2115                     {
2116                         if( ( strcmp( curattr->name, "model_name" ) == 0 ) &&
2117                             ( strncmp( curattr->value, PROD_NAME,
2118                                        sizeof(PROD_NAME) ) == 0 ) )
2119                         {
2120                             *p_ipod_id = strtoll( curdev->name, NULL, 16 );
2121                             i_ret = 0;
2122                             break;
2123                         }
2124                     }
2125                 }
2126
2127                 if( !i_ret ) break;
2128             }
2129         }
2130
2131         sysfs_close_bus( bus );
2132     }
2133 #endif
2134
2135     return i_ret;
2136 }
2137