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