1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2004 the VideoLAN team
7 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8 * Sam Hocevar <sam@zoy.org>
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.
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.
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 *****************************************************************************/
29 #include <vlc_common.h>
43 # if !defined( UNDER_CE )
51 #ifdef HAVE_SYS_STAT_H
52 # include <sys/stat.h>
54 #include <sys/types.h>
56 /* In Solaris (and perhaps others) PATH_MAX is in limits.h. */
60 # include <mach/mach.h>
61 # include <IOKit/IOKitLib.h>
62 # include <CoreFoundation/CFNumber.h>
65 #ifdef HAVE_SYSFS_LIBSYSFS_H
66 # include <sysfs/libsysfs.h>
70 #include "drmstables.h"
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 *****************************************************************************/
81 uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
82 uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
85 #define Digest DigestMD5
87 /*****************************************************************************
88 * shuffle_s: shuffle structure
89 *****************************************************************************
90 * This structure stores the static information needed to shuffle data using
92 *****************************************************************************/
96 uint32_t p_commands[ 20 ];
97 uint32_t p_bordel[ 16 ];
100 #define SWAP( a, b ) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
102 /*****************************************************************************
103 * drms_s: DRMS structure
104 *****************************************************************************
105 * This structure stores the static information needed to decrypt DRMS data.
106 *****************************************************************************/
111 uint8_t p_iviv[ 16 ];
117 char psz_homedir[ PATH_MAX ];
120 /*****************************************************************************
122 *****************************************************************************/
123 static void InitAES ( struct aes_s *, uint32_t * );
124 static void DecryptAES ( struct aes_s *, uint32_t *, const uint32_t * );
126 static void InitShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
127 static void DoShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
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 * );
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 * );
148 static int GetSCIData ( char *, uint32_t **, uint32_t * );
149 static int HashSystemInfo ( uint32_t * );
150 static int GetiPodID ( int64_t * );
152 #ifdef WORDS_BIGENDIAN
153 /*****************************************************************************
154 * Reverse: reverse byte order
155 *****************************************************************************/
156 static inline void Reverse( uint32_t *p_buffer, int n )
160 for( i = 0; i < n; i++ )
162 p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
165 # define REVERSE( p, n ) Reverse( p, n )
167 # define REVERSE( p, n )
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 )
177 for( i = 0; i < 4; i++ )
179 p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
183 /*****************************************************************************
184 * drms_alloc: allocate a DRMS structure
185 *****************************************************************************/
186 void *drms_alloc( const char *psz_homedir )
188 struct drms_s *p_drms;
190 p_drms = calloc( 1, sizeof(struct drms_s) );
194 strncpy( p_drms->psz_homedir, psz_homedir, PATH_MAX );
195 p_drms->psz_homedir[ PATH_MAX - 1 ] = '\0';
197 return (void *)p_drms;
200 /*****************************************************************************
201 * drms_free: free a previously allocated DRMS structure
202 *****************************************************************************/
203 void drms_free( void *_p_drms )
205 struct drms_s *p_drms = (struct drms_s *)_p_drms;
207 free( (void *)p_drms->p_name );
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 )
216 struct drms_s *p_drms = (struct drms_s *)_p_drms;
217 uint32_t p_key_buf[ 4 ];
218 unsigned int i_blocks;
220 /* AES is a block cypher, round down the byte count */
221 i_blocks = i_bytes / 16;
222 i_bytes = i_blocks * 16;
224 /* Initialise the key */
228 memcpy( p_key, p_drms->p_key, 16 );
236 REVERSE( p_buffer, 4 );
237 DecryptAES( &p_drms->aes, p_tmp, p_buffer );
238 BlockXOR( p_tmp, p_key, p_tmp );
240 /* Use the previous scrambled data as the key for next block */
241 memcpy( p_key, p_buffer, 16 );
243 /* Copy unscrambled data back to the buffer */
244 memcpy( p_buffer, p_tmp, 16 );
245 REVERSE( p_buffer, 4 );
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 )
256 struct drms_s *p_drms = (struct drms_s *)_p_drms;
258 memcpy( p_key, p_drms->p_key, 16 );
261 /*****************************************************************************
262 * drms_init: initialise a DRMS structure
263 *****************************************************************************
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 )
276 struct drms_s *p_drms = (struct drms_s *)_p_drms;
282 if( i_len < sizeof(p_drms->i_user) )
288 p_drms->i_user = U32_AT( p_info );
292 if( i_len < sizeof(p_drms->i_key) )
298 p_drms->i_key = U32_AT( p_info );
302 if( i_len < sizeof(p_drms->p_key) )
308 memcpy( p_drms->p_iviv, p_info, 16 );
312 p_drms->p_name = (uint8_t*) strdup( (char *)p_info );
314 if( p_drms->p_name == NULL )
322 uint32_t p_priv[ 64 ];
332 AddMD5( &md5, p_drms->p_name, strlen( (char *)p_drms->p_name ) );
333 AddMD5( &md5, p_drms->p_iviv, 16 );
336 if( p_drms->i_user == 0 && p_drms->i_key == 0 )
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 );
344 i_ret = GetUserKey( p_drms, p_drms->p_key );
351 InitAES( &p_drms->aes, p_drms->p_key );
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 );
358 if( p_priv[ 0 ] != 0x6e757469 ) /* itun */
364 InitAES( &p_drms->aes, p_priv + 6 );
365 memcpy( p_drms->p_key, p_priv + 12, 16 );
367 free( (void *)p_drms->p_name );
368 p_drms->p_name = NULL;
376 /* The following functions are local */
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 )
386 uint32_t i_key, i_seed;
388 memset( p_aes->pp_enc_keys[1], 0, 16 );
389 memcpy( p_aes->pp_enc_keys[0], p_key, 16 );
391 /* Generate the key tables */
392 i_seed = p_aes->pp_enc_keys[ 0 ][ 3 ];
394 for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
398 i_seed = AES_ROR( i_seed, 8 );
400 j = p_aes_table[ i_key ];
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 );
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;
419 memcpy( p_aes->pp_dec_keys[ 0 ],
420 p_aes->pp_enc_keys[ 0 ], 16 );
422 for( i = 1; i < AES_KEY_COUNT; i++ )
424 for( t = 0; t < 4; t++ )
426 uint32_t j, k, l, m, n;
428 j = p_aes->pp_enc_keys[ i ][ t ];
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);
436 n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
438 p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
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 )
449 uint32_t p_wtxt[ 4 ]; /* Working cyphertext */
451 unsigned int i_round, t;
453 for( t = 0; t < 4; t++ )
455 /* FIXME: are there any endianness issues here? */
456 p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
460 for( i_round = 0; i_round < (AES_KEY_COUNT - 1); i_round++ )
462 for( t = 0; t < 4; t++ )
464 p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
467 for( t = 0; t < 4; t++ )
469 p_wtxt[ t ] = p_tmp[ t ]
470 ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - i_round ][ t ];
474 /* Final round (9) */
475 for( t = 0; t < 4; t++ )
477 p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
478 p_dest[ t ] ^= p_aes->pp_dec_keys[ 0 ][ t ];
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,
491 char p_secret1[] = "Tv!*";
492 static const char p_secret2[] = "____v8rhvsaAvOKM____FfUH%798=[;."
493 "____f8677680a634____ba87fnOIf)(*";
496 p_shuffle->i_version = i_version;
498 /* Fill p_commands using the key and a secret seed */
499 for( i = 0; i < 20; i++ )
505 AddMD5( &md5, (const uint8_t *)p_sys_key, 16 );
506 AddMD5( &md5, (const uint8_t *)p_secret1, 4 );
511 REVERSE( md5.p_digest, 1 );
512 i_hash = ((int32_t)U32_AT(md5.p_digest)) % 1024;
514 p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
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++ )
521 p_shuffle->p_bordel[ 4 * i ] = U32_AT(p_sys_key + i);
522 REVERSE( p_shuffle->p_bordel + 4 * i + 1, 3 );
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 )
536 uint32_t p_big_bordel[ 16 ];
537 uint32_t *p_bordel = p_shuffle->p_bordel;
540 static const uint32_t p_secret3[] =
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
550 static const uint32_t i_secret3 = sizeof(p_secret3)/sizeof(p_secret3[0]);
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' */
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++ )
561 uint8_t i_command, i_index;
563 if( !p_shuffle->p_commands[ i ] )
568 i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
569 i_index = p_shuffle->p_commands[ i ] & 0xff;
574 p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
575 + p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
578 p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
581 p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
584 p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
589 if( p_shuffle->i_version == 0x01000300 )
591 DoExtShuffle( p_bordel );
594 /* Convert our newly randomised p_bordel to big endianness and take
597 for( i = 0; i < 16; i++ )
599 p_big_bordel[ i ] = U32_AT(p_bordel + i);
601 AddMD5( &md5, (const uint8_t *)p_big_bordel, 64 );
602 if( p_shuffle->i_version == 0x01000300 )
604 uint32_t p_tmp3[i_secret3];
605 char p_tmp4[i_secret4];
607 memcpy( p_tmp3, p_secret3, sizeof(p_secret3) );
608 REVERSE( p_tmp3, i_secret3 );
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] );
616 AddMD5( &md5, (const uint8_t *)p_tmp3, sizeof(p_secret3) );
617 AddMD5( &md5, (const uint8_t *)p_tmp4, i_secret4 );
621 /* XOR our buffer with the computed checksum */
622 for( i = 0; i < i_size; i++ )
624 p_buffer[ i ] ^= md5.p_digest[ i ];
628 /*****************************************************************************
629 * DoExtShuffle: extended shuffle
630 *****************************************************************************
631 * This is even uglier.
632 *****************************************************************************/
633 static void DoExtShuffle( uint32_t * p_bordel )
637 i_ret = FirstPass( p_bordel );
639 SecondPass( p_bordel, i_ret );
641 ThirdPass( p_bordel );
643 FourthPass( p_bordel );
646 static uint32_t FirstPass( uint32_t * p_bordel )
648 uint32_t i, i_cmd, i_ret = 5;
650 TinyShuffle1( p_bordel );
656 p_bordel[ 1 ] += 0x10000000;
657 p_bordel[ 3 ] += 0x12777;
659 if( (p_bordel[ 10 ] & 1) && i_ret )
662 p_bordel[ 1 ] -= p_bordel[ 2 ];
663 p_bordel[ 11 ] += p_bordel[ 12 ];
667 if( (p_bordel[ 1 ] + p_bordel[ 2 ]) >= 0x7D0 )
669 switch( ((p_bordel[ 3 ] ^ 0x567F) >> 2) & 7 )
672 for( i = 0; i < 3; i++ )
674 if( p_bordel[ i + 10 ] > 0x4E20 )
676 p_bordel[ i + 1 ] += p_bordel[ i + 2 ];
681 p_bordel[ 1 ] -= p_bordel[ 2 ];
684 p_bordel[ 11 ] += p_bordel[ 12 ];
687 p_bordel[ 3 ] ^= p_bordel[ 4 ];
690 p_bordel[ 13 ] &= p_bordel[ 14 ];
693 p_bordel[ 0 ] |= p_bordel[ 1 ];
705 for( i = 0, i_cmd = 0; i < 16; i++ )
707 if( p_bordel[ i ] < p_bordel[ i_cmd ] )
713 if( i_ret && i_cmd != 5 )
721 p_bordel[ 8 ] &= p_bordel[ 6 ] >> 1;
725 for( i = 0; i < 3; i++ )
728 if( p_bordel[ 11 ] & 5 )
730 p_bordel[ 8 ] += p_bordel[ 9 ];
740 i_cmd = (p_bordel[ 15 ] + 0x93) >> 3;
741 if( p_bordel[ 15 ] & 0x100 )
750 while( p_bordel[ 11 ] & 1 )
752 p_bordel[ 11 ] >>= 1;
757 p_bordel[ 14 ] -= 0x19FE;
769 i_cmd = ((p_bordel[ 3 ] + p_bordel[ 4 ] + 10) >> 1) - p_bordel[ 4 ];
777 p_bordel[ 14 ] >>= 1;
786 p_bordel[ 15 ] &= 0x55;
789 p_bordel[ 2 ] &= 0xB62FC;
795 TinyShuffle2( p_bordel );
800 static void SecondPass( uint32_t * p_bordel, uint32_t i_tmp )
802 uint32_t i, i_cmd, i_jc = 5;
804 TinyShuffle3( p_bordel );
806 for( i = 0, i_cmd = 0; i < 16; i++ )
808 if( p_bordel[ i ] > p_bordel[ i_cmd ] )
817 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
823 if( (p_bordel[ 9 ] & 0x7777) == 0x3333 )
830 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
839 p_bordel[ 1 ] -= p_bordel[ 5 ];
840 for( i = 0; i < 3; i++ )
842 switch( p_bordel[ 1 ] & 3 )
851 p_bordel[ 13 ] &= 0xFEFEFEF7;
854 p_bordel[ 8 ] |= 0x80080011;
866 p_bordel[ 15 ] ^= 0x18547EFF;
872 switch( ( p_bordel[ 12 ] + p_bordel[ 13 ] + p_bordel[ 6 ] ) % 5 )
892 i = 3; /* Restart the whole loop */
897 TinyShuffle4( p_bordel );
901 TinyShuffle5( p_bordel );
903 switch( ( p_bordel[ 2 ] * 2 + 15 ) % 5 )
906 if( ( p_bordel[ 3 ] + i_tmp ) <=
907 ( p_bordel[ 1 ] + p_bordel[ 15 ] ) )
913 p_bordel[ 10 ] -= 0x13;
920 if( !( p_bordel[ 2 ] & 1 ) || i_jc == 0 )
926 p_bordel[ 2 ] += 0x13;
930 p_bordel[ 2 ] &= 0x10076000;
933 static void ThirdPass( uint32_t * p_bordel )
937 i_cmd = ((p_bordel[ 7 ] + p_bordel[ 14 ] + 10) >> 1) - p_bordel[ 14 ];
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 ];
955 p_bordel[ 1 ] += p_bordel[ 4 ];
956 p_bordel[ 0 ] += p_bordel[ 3 ];
957 TinyShuffle6( p_bordel );
960 if( (p_bordel[ 11 ] & p_bordel[ 2 ]) > 0x211B )
969 p_bordel[ 9 ] ^= p_bordel[ 2 ];
972 p_bordel[ 2 ] ^= (p_bordel[ 1 ] & p_bordel[ 13 ]);
975 p_bordel[ 0 ] -= p_bordel[ 11 ] & p_bordel[ 15 ];
978 p_bordel[ 6 ] >>= (p_bordel[ 14 ] & 3);
982 SWAP( p_bordel[ 0 ], p_bordel[ 10 ] );
984 TinyShuffle6( p_bordel );
989 static void FourthPass( uint32_t * p_bordel )
993 TinyShuffle7( p_bordel );
995 switch( p_bordel[ 5 ] % 5)
1001 p_bordel[ 11 ] ^= (p_bordel[ 3 ] + p_bordel[ 6 ] + p_bordel[ 8 ]);
1004 for( i = 4; i < 15 && (p_bordel[ i ] & 5) == 0; i++ )
1006 SWAP( p_bordel[ i ], p_bordel[ 15 - i ] );
1010 p_bordel[ 12 ] -= 1;
1011 p_bordel[ 13 ] += 1;
1012 p_bordel[ 2 ] -= 0x64;
1013 p_bordel[ 3 ] += 0x64;
1014 TinyShuffle8( p_bordel );
1018 for( i = 0, j = 0; i < 16; i++ )
1020 if( p_bordel[ i ] > p_bordel[ j ] )
1026 switch( p_bordel[ j ] % 100 )
1029 SWAP( p_bordel[ 0 ], p_bordel[ j ] );
1032 p_bordel[ 1 ] >>= 1;
1033 p_bordel[ 2 ] <<= 1;
1034 p_bordel[ 14 ] >>= 3;
1035 p_bordel[ 15 ] <<= 4;
1038 p_bordel[ j ] += p_bordel[ 13 ];
1041 p_bordel[ 1 ] += 0x20E;
1042 p_bordel[ 5 ] += 0x223D;
1043 p_bordel[ 13 ] -= 0x576;
1044 p_bordel[ 15 ] += 0x576;
1047 p_bordel[ 2 ] -= 0x64;
1048 p_bordel[ 3 ] += 0x64;
1049 p_bordel[ 12 ] -= 1;
1050 p_bordel[ 13 ] += 1;
1054 p_bordel[ j ] += p_bordel[ 13 ];
1058 TinyShuffle8( p_bordel );
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 )
1068 uint32_t i_cmd = (p_bordel[ 5 ] + 10) >> 2;
1070 if( p_bordel[ 5 ] > 0x7D0 )
1084 if( p_bordel[ 4 ] & 5 )
1086 p_bordel[ 1 ] ^= 0x4D;
1090 p_bordel[ 12 ] += 5;
1095 static void TinyShuffle2( uint32_t * p_bordel )
1099 for( i = 0, j = 0; i < 16; i++ )
1101 if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) )
1109 for( ; j < 15; j++ )
1111 p_bordel[ j ] += p_bordel[ j + 1 ];
1116 p_bordel[ 2 ] &= 0xB62FC;
1120 static void TinyShuffle3( uint32_t * p_bordel )
1122 uint32_t i_cmd = p_bordel[ 6 ] + 0x194B;
1124 if( p_bordel[ 6 ] > 0x2710 )
1132 p_bordel[ 3 ] += 0x19FE;
1135 p_bordel[ 7 ] -= p_bordel[ 3 ] >> 2;
1138 p_bordel[ 5 ] ^= 0x248A;
1143 static void TinyShuffle4( uint32_t * p_bordel )
1147 for( i = 0, j = 0; i < 16; i++ )
1149 if( p_bordel[ i ] < p_bordel[ j ] )
1155 if( (p_bordel[ j ] % (j + 1)) > 10 )
1158 p_bordel[ 2 ] += 0x13;
1159 p_bordel[ 12 ] += 1;
1163 static void TinyShuffle5( uint32_t * p_bordel )
1167 p_bordel[ 2 ] &= 0x7F3F;
1169 for( i = 0; i < 5; i++ )
1171 switch( ( p_bordel[ 2 ] + 10 + i ) % 5 )
1174 p_bordel[ 12 ] &= p_bordel[ 2 ];
1177 p_bordel[ 3 ] ^= p_bordel[ 15 ];
1180 p_bordel[ 15 ] += 0x576;
1183 p_bordel[ 7 ] -= 0x2D;
1186 p_bordel[ 1 ] <<= 1;
1192 static void TinyShuffle6( uint32_t * p_bordel )
1196 for( i = 0; i < 8; i++ )
1198 j = p_bordel[ 3 ] & 0x7514 ? 5 : 7;
1199 SWAP( p_bordel[ i ], p_bordel[ i + j ] );
1203 static void TinyShuffle7( uint32_t * p_bordel )
1207 i = (((p_bordel[ 9 ] + p_bordel[ 15 ] + 12) >> 2) - p_bordel[ 4 ]) & 7;
1211 SWAP( p_bordel[ i ], p_bordel[ i + 3 ] );
1214 SWAP( p_bordel[ 1 ], p_bordel[ 10 ] );
1217 static void TinyShuffle8( uint32_t * p_bordel )
1221 i = (p_bordel[ 0 ] & p_bordel[ 6 ]) & 0xF;
1223 switch( p_bordel[ i ] % 1000 )
1226 if( (p_bordel[ i ] & 0x777) > (p_bordel[ 7 ] & 0x5555) )
1228 p_bordel[ i ] ^= p_bordel[ 5 ] & p_bordel[ 3 ];
1232 p_bordel[ 15 ] &= 0x5555;
1235 p_bordel[ i ] ^= p_bordel[ 15 ];
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 ] );
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;
1253 p_bordel[ 12 ] -= p_bordel[ i ];
1254 p_bordel[ 13 ] += p_bordel[ i ];
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 ];
1265 p_bordel[ i + 1 ] >>= 1;
1266 p_bordel[ i + 2 ] <<= 4;
1267 p_bordel[ i + 3 ] >>= 3;
1270 p_bordel[ 1 ] += 0x20E;
1271 p_bordel[ 5 ] += 0x223D;
1272 p_bordel[ 13 ] -= 0x576;
1273 p_bordel[ 15 ] += 0x576;
1276 if( (p_bordel[ i ] ^ 0x8765F441) < 0x2710 )
1278 SWAP( p_bordel[ 0 ], p_bordel[ 1 ] );
1282 SWAP( p_bordel[ 1 ], p_bordel[ 11 ] );
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 )
1295 static const char p_secret5[ 8 ] = "YuaFlafu";
1296 static const char p_secret6[ 8 ] = "zPif98ga";
1299 uint32_t p_system_hash[ 4 ];
1301 /* Compute the MD5 hash of our system info */
1302 if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) ||
1303 ( b_ipod && GetiPodID( &i_ipod_id ) ) )
1308 /* Combine our system info hash with additional secret data. The resulting
1309 * MD5 hash will be our system key. */
1311 AddMD5( &md5, (const uint8_t*)p_secret5, 8 );
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 );
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) );
1330 memcpy( p_sys_key, md5.p_digest, 16 );
1336 # define DRMS_DIRNAME "drms"
1338 # define DRMS_DIRNAME ".drms"
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 )
1349 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1352 char psz_path[ PATH_MAX ];
1354 snprintf( psz_path, PATH_MAX - 1,
1355 "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
1357 #if defined( WIN32 )
1358 if( !mkdir( psz_path ) || errno == EEXIST )
1360 if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
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 );
1366 file = utf8_fopen( psz_path, "wb" );
1369 i_ret = fwrite( p_user_key, sizeof(uint32_t),
1370 4, file ) == 4 ? 0 : -1;
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 )
1385 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1388 char psz_path[ PATH_MAX ];
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 );
1394 file = utf8_fopen( psz_path, "rb" );
1397 i_ret = fread( p_user_key, sizeof(uint32_t),
1398 4, file ) == 4 ? 0 : -1;
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 )
1414 static const char p_secret7[] = "mUfnpognadfgf873";
1415 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1417 struct shuffle_s shuffle;
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 ];
1428 if( ReadUserKey( p_drms, p_user_key ) == 0 )
1430 REVERSE( p_user_key, 4 );
1434 psz_ipod = getenv( "IPOD" );
1436 if( GetSystemKey( p_sys_key, psz_ipod ? true : false ) )
1441 if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
1446 /* Phase 1: unscramble the SCI data using the system key and shuffle
1447 * it using DoShuffle(). */
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;
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 ] );
1460 memcpy( p_sci_key, p_secret7, 16 );
1461 REVERSE( p_sci_key, 4 );
1465 uint32_t p_tmp[ 4 ];
1467 REVERSE( p_buffer, 4 );
1468 DecryptAES( &aes, p_tmp, p_buffer );
1469 BlockXOR( p_tmp, p_sci_key, p_tmp );
1471 /* Use the previous scrambled data as the key for next block */
1472 memcpy( p_sci_key, p_buffer, 16 );
1474 /* Shuffle the decrypted data using a custom routine */
1475 DoShuffle( &shuffle, p_tmp, 4 );
1477 /* Copy this block back to p_buffer */
1478 memcpy( p_buffer, p_tmp, 16 );
1483 if( i_remaining >= 4 )
1485 REVERSE( p_buffer, i_remaining / 4 );
1486 DoShuffle( &shuffle, p_buffer, i_remaining / 4 );
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. */
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;
1501 while( i_sci_size >= 20 && i > 0 )
1503 if( p_sci0 == NULL )
1505 i_sci_size -= 18 * sizeof(uint32_t);
1506 if( i_sci_size < 20 )
1512 REVERSE( p_sci1 + 17, 1 );
1513 y = U32_AT( p_sci1 + 17 );
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) ) ) ) )
1531 memcpy( p_user_key, p_sci1 + 1, 16 );
1532 REVERSE( p_sci1 + 1, 4 );
1533 WriteUserKey( p_drms, p_sci1 + 1 );
1540 i_sci_size -= 5 * sizeof(uint32_t);
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 )
1557 char *psz_path = NULL;
1558 char p_tmp[ 4 * PATH_MAX ];
1561 if( psz_ipod == NULL )
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 )
1569 strcat(p_tmp, SCIfile);
1570 p_tmp[sizeof( p_tmp ) - 1] = '\0';
1576 #define ISCINFO "iSCInfo"
1577 if( strstr( psz_ipod, ISCINFO ) == NULL )
1579 snprintf( p_tmp, sizeof(p_tmp) - 1,
1580 "%s/iPod_Control/iTunes/" ISCINFO "2", psz_ipod );
1585 psz_path = psz_ipod;
1589 if( psz_path == NULL )
1594 file = utf8_fopen( psz_path, "rb" );
1599 if( !fstat( fileno( file ), &st ) && st.st_size >= 4 )
1601 *pp_sci = malloc( st.st_size );
1602 if( *pp_sci != NULL )
1604 if( fread( *pp_sci, 1, st.st_size,
1605 file ) == (size_t)st.st_size )
1607 *pi_sci_size = st.st_size;
1612 free( (void *)*pp_sci );
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 )
1642 static const LPCTSTR p_reg_keys[ 3 ][ 2 ] =
1645 _T("HARDWARE\\DESCRIPTION\\System"),
1646 _T("SystemBiosVersion")
1650 _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
1651 _T("ProcessorNameString")
1655 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
1662 AddMD5( &md5, "cache-control", 13 );
1663 AddMD5( &md5, "Ethernet", 8 );
1665 GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
1666 NULL, NULL, NULL, 0 );
1667 AddMD5( &md5, (const uint8_t *)&i_serial, 4 );
1669 for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
1671 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
1672 0, KEY_READ, &i_key ) != ERROR_SUCCESS )
1677 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1678 NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
1680 RegCloseKey( i_key );
1684 p_reg_buf = malloc( i_size );
1686 if( p_reg_buf != NULL )
1688 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1689 NULL, NULL, p_reg_buf,
1690 &i_size ) == ERROR_SUCCESS )
1692 AddMD5( &md5, (const uint8_t *)p_reg_buf, i_size );
1698 RegCloseKey( i_key );
1707 memcpy( p_system_hash, md5.p_digest, 16 );
1712 /*****************************************************************************
1713 * GetiPodID: Get iPod ID
1714 *****************************************************************************
1715 * This function gets the iPod ID.
1716 *****************************************************************************/
1717 static int GetiPodID( int64_t *p_ipod_id )
1721 #define PROD_NAME "iPod"
1722 #define VENDOR_NAME "Apple Computer, Inc."
1724 char *psz_ipod_id = getenv( "IPODID" );
1725 if( psz_ipod_id != NULL )
1727 *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
1735 io_iterator_t iterator;
1736 CFMutableDictionaryRef match_dic;
1737 CFMutableDictionaryRef smatch_dic;
1739 if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
1741 smatch_dic = IOServiceMatching( "IOFireWireUnit" );
1742 match_dic = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
1743 &kCFTypeDictionaryKeyCallBacks,
1744 &kCFTypeDictionaryValueCallBacks );
1746 if( smatch_dic != NULL && match_dic != NULL )
1748 CFDictionarySetValue( smatch_dic,
1749 CFSTR("FireWire Vendor Name"),
1750 CFSTR(VENDOR_NAME) );
1751 CFDictionarySetValue( smatch_dic,
1752 CFSTR("FireWire Product Name"),
1755 CFDictionarySetValue( match_dic,
1756 CFSTR(kIOPropertyMatchKey),
1759 if( IOServiceGetMatchingServices( port, match_dic,
1760 &iterator ) == KERN_SUCCESS )
1762 while( ( device = IOIteratorNext( iterator ) ) != 0 )
1764 value = IORegistryEntryCreateCFProperty( device,
1765 CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );
1769 if( CFGetTypeID( value ) == CFNumberGetTypeID() )
1772 CFNumberGetValue( (CFNumberRef)value,
1773 kCFNumberLongLongType,
1775 *p_ipod_id = i_ipod_id;
1782 IOObjectRelease( device );
1787 IOObjectRelease( iterator );
1789 CFRelease( match_dic );
1792 mach_port_deallocate( mach_task_self(), port );
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;
1802 bus = sysfs_open_bus( "ieee1394" );
1805 devlist = sysfs_get_bus_devices( bus );
1806 if( devlist != NULL )
1808 dlist_for_each_data( devlist, curdev, struct sysfs_device )
1810 attributes = sysfs_get_device_attributes( curdev );
1811 if( attributes != NULL )
1813 dlist_for_each_data( attributes, curattr,
1814 struct sysfs_attribute )
1816 if( ( strcmp( curattr->name, "model_name" ) == 0 ) &&
1817 ( strncmp( curattr->value, PROD_NAME,
1818 sizeof(PROD_NAME) ) == 0 ) )
1820 *p_ipod_id = strtoll( curdev->name, NULL, 16 );
1831 sysfs_close_bus( bus );
1838 #else /* !defined( UNDER_CE ) */
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; }
1846 #endif /* defined( UNDER_CE ) */