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