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