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