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>
32 #include <vlc_charset.h>
43 # if !defined( UNDER_CE )
51 #ifdef HAVE_SYS_STAT_H
52 # include <sys/stat.h>
54 #ifdef HAVE_SYS_TYPES_H
55 # include <sys/types.h>
58 /* In Solaris (and perhaps others) PATH_MAX is in limits.h. */
62 # include <mach/mach.h>
63 # include <IOKit/IOKitLib.h>
64 # include <CoreFoundation/CFNumber.h>
67 #ifdef HAVE_SYSFS_LIBSYSFS_H
68 # include <sysfs/libsysfs.h>
72 #include "drmstables.h"
74 #if !defined( UNDER_CE )
75 /*****************************************************************************
76 * aes_s: AES keys structure
77 *****************************************************************************
78 * This structure stores a set of keys usable for encryption and decryption
79 * with the AES/Rijndael algorithm.
80 *****************************************************************************/
83 uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
84 uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
87 #define Digest DigestMD5
89 /*****************************************************************************
90 * shuffle_s: shuffle structure
91 *****************************************************************************
92 * This structure stores the static information needed to shuffle data using
94 *****************************************************************************/
98 uint32_t p_commands[ 20 ];
99 uint32_t p_bordel[ 16 ];
102 #define SWAP( a, b ) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
104 /*****************************************************************************
105 * drms_s: DRMS structure
106 *****************************************************************************
107 * This structure stores the static information needed to decrypt DRMS data.
108 *****************************************************************************/
113 uint8_t p_iviv[ 16 ];
119 char psz_homedir[ PATH_MAX ];
122 /*****************************************************************************
124 *****************************************************************************/
125 static void InitAES ( struct aes_s *, uint32_t * );
126 static void DecryptAES ( struct aes_s *, uint32_t *, const uint32_t * );
128 static void InitShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
129 static void DoShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
131 static uint32_t FirstPass ( uint32_t * );
132 static void SecondPass ( uint32_t *, uint32_t );
133 static void ThirdPass ( uint32_t * );
134 static void FourthPass ( uint32_t * );
135 static void TinyShuffle1 ( uint32_t * );
136 static void TinyShuffle2 ( uint32_t * );
137 static void TinyShuffle3 ( uint32_t * );
138 static void TinyShuffle4 ( uint32_t * );
139 static void TinyShuffle5 ( uint32_t * );
140 static void TinyShuffle6 ( uint32_t * );
141 static void TinyShuffle7 ( uint32_t * );
142 static void TinyShuffle8 ( uint32_t * );
143 static void DoExtShuffle ( uint32_t * );
145 static int GetSystemKey ( uint32_t *, bool );
146 static int WriteUserKey ( void *, uint32_t * );
147 static int ReadUserKey ( void *, uint32_t * );
148 static int GetUserKey ( void *, uint32_t * );
150 static int GetSCIData ( char *, uint32_t **, uint32_t * );
151 static int HashSystemInfo ( uint32_t * );
152 static int GetiPodID ( int64_t * );
154 #ifdef WORDS_BIGENDIAN
155 /*****************************************************************************
156 * Reverse: reverse byte order
157 *****************************************************************************/
158 static inline void Reverse( uint32_t *p_buffer, int n )
162 for( i = 0; i < n; i++ )
164 p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
167 # define REVERSE( p, n ) Reverse( p, n )
169 # define REVERSE( p, n )
172 /*****************************************************************************
173 * BlockXOR: XOR two 128 bit blocks
174 *****************************************************************************/
175 static inline void BlockXOR( uint32_t *p_dest, uint32_t *p_s1, uint32_t *p_s2 )
179 for( i = 0; i < 4; i++ )
181 p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
185 /*****************************************************************************
186 * drms_alloc: allocate a DRMS structure
187 *****************************************************************************/
188 void *drms_alloc( const char *psz_homedir )
190 struct drms_s *p_drms;
192 p_drms = calloc( 1, sizeof(struct drms_s) );
196 strncpy( p_drms->psz_homedir, psz_homedir, PATH_MAX );
197 p_drms->psz_homedir[ PATH_MAX - 1 ] = '\0';
199 return (void *)p_drms;
202 /*****************************************************************************
203 * drms_free: free a previously allocated DRMS structure
204 *****************************************************************************/
205 void drms_free( void *_p_drms )
207 struct drms_s *p_drms = (struct drms_s *)_p_drms;
209 free( (void *)p_drms->p_name );
213 /*****************************************************************************
214 * drms_decrypt: unscramble a chunk of data
215 *****************************************************************************/
216 void drms_decrypt( void *_p_drms, uint32_t *p_buffer, uint32_t i_bytes, uint32_t *p_key )
218 struct drms_s *p_drms = (struct drms_s *)_p_drms;
219 uint32_t p_key_buf[ 4 ];
220 unsigned int i_blocks;
222 /* AES is a block cypher, round down the byte count */
223 i_blocks = i_bytes / 16;
224 i_bytes = i_blocks * 16;
226 /* Initialise the key */
230 memcpy( p_key, p_drms->p_key, 16 );
238 REVERSE( p_buffer, 4 );
239 DecryptAES( &p_drms->aes, p_tmp, p_buffer );
240 BlockXOR( p_tmp, p_key, p_tmp );
242 /* Use the previous scrambled data as the key for next block */
243 memcpy( p_key, p_buffer, 16 );
245 /* Copy unscrambled data back to the buffer */
246 memcpy( p_buffer, p_tmp, 16 );
247 REVERSE( p_buffer, 4 );
253 /*****************************************************************************
254 * drms_get_p_key: copy the p_key into user buffer
255 ****************************************************************************/
256 void drms_get_p_key( void *_p_drms, uint32_t *p_key )
258 struct drms_s *p_drms = (struct drms_s *)_p_drms;
260 memcpy( p_key, p_drms->p_key, 16 );
263 /*****************************************************************************
264 * drms_init: initialise a DRMS structure
265 *****************************************************************************
269 * -2: invalid argument
270 * -3: could not get system key
271 * -4: could not get SCI data
272 * -5: no user key found in SCI data
273 * -6: invalid user key
274 *****************************************************************************/
275 int drms_init( void *_p_drms, uint32_t i_type,
276 uint8_t *p_info, uint32_t i_len )
278 struct drms_s *p_drms = (struct drms_s *)_p_drms;
284 if( i_len < sizeof(p_drms->i_user) )
290 p_drms->i_user = U32_AT( p_info );
294 if( i_len < sizeof(p_drms->i_key) )
300 p_drms->i_key = U32_AT( p_info );
304 if( i_len < sizeof(p_drms->p_key) )
310 memcpy( p_drms->p_iviv, p_info, 16 );
314 p_drms->p_name = (uint8_t*) strdup( (char *)p_info );
316 if( p_drms->p_name == NULL )
324 uint32_t p_priv[ 64 ];
334 AddMD5( &md5, p_drms->p_name, strlen( (char *)p_drms->p_name ) );
335 AddMD5( &md5, p_drms->p_iviv, 16 );
338 if( p_drms->i_user == 0 && p_drms->i_key == 0 )
340 static const char p_secret[] = "tr1-th3n.y00_by3";
341 memcpy( p_drms->p_key, p_secret, 16 );
342 REVERSE( p_drms->p_key, 4 );
346 i_ret = GetUserKey( p_drms, p_drms->p_key );
353 InitAES( &p_drms->aes, p_drms->p_key );
355 memcpy( p_priv, p_info, 64 );
356 memcpy( p_drms->p_key, md5.p_digest, 16 );
357 drms_decrypt( p_drms, p_priv, 64, NULL );
358 REVERSE( p_priv, 64 );
360 if( p_priv[ 0 ] != 0x6e757469 ) /* itun */
366 InitAES( &p_drms->aes, p_priv + 6 );
367 memcpy( p_drms->p_key, p_priv + 12, 16 );
369 free( (void *)p_drms->p_name );
370 p_drms->p_name = NULL;
378 /* The following functions are local */
380 /*****************************************************************************
381 * InitAES: initialise AES/Rijndael encryption/decryption tables
382 *****************************************************************************
383 * The Advanced Encryption Standard (AES) is described in RFC 3268
384 *****************************************************************************/
385 static void InitAES( struct aes_s *p_aes, uint32_t *p_key )
388 uint32_t i_key, i_seed;
390 memset( p_aes->pp_enc_keys[1], 0, 16 );
391 memcpy( p_aes->pp_enc_keys[0], p_key, 16 );
393 /* Generate the key tables */
394 i_seed = p_aes->pp_enc_keys[ 0 ][ 3 ];
396 for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
400 i_seed = AES_ROR( i_seed, 8 );
402 j = p_aes_table[ i_key ];
404 j ^= p_aes_encrypt[ (i_seed >> 24) & 0xff ]
405 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 16) & 0xff ], 8 )
406 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 8) & 0xff ], 16 )
407 ^ AES_ROR( p_aes_encrypt[ i_seed & 0xff ], 24 );
409 j ^= p_aes->pp_enc_keys[ i_key ][ 0 ];
410 p_aes->pp_enc_keys[ i_key + 1 ][ 0 ] = j;
411 j ^= p_aes->pp_enc_keys[ i_key ][ 1 ];
412 p_aes->pp_enc_keys[ i_key + 1 ][ 1 ] = j;
413 j ^= p_aes->pp_enc_keys[ i_key ][ 2 ];
414 p_aes->pp_enc_keys[ i_key + 1 ][ 2 ] = j;
415 j ^= p_aes->pp_enc_keys[ i_key ][ 3 ];
416 p_aes->pp_enc_keys[ i_key + 1 ][ 3 ] = j;
421 memcpy( p_aes->pp_dec_keys[ 0 ],
422 p_aes->pp_enc_keys[ 0 ], 16 );
424 for( i = 1; i < AES_KEY_COUNT; i++ )
426 for( t = 0; t < 4; t++ )
428 uint32_t j, k, l, m, n;
430 j = p_aes->pp_enc_keys[ i ][ t ];
432 k = (((j >> 7) & 0x01010101) * 27) ^ ((j & 0xff7f7f7f) << 1);
433 l = (((k >> 7) & 0x01010101) * 27) ^ ((k & 0xff7f7f7f) << 1);
434 m = (((l >> 7) & 0x01010101) * 27) ^ ((l & 0xff7f7f7f) << 1);
438 n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
440 p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
445 /*****************************************************************************
446 * DecryptAES: decrypt an AES/Rijndael 128 bit block
447 *****************************************************************************/
448 static void DecryptAES( struct aes_s *p_aes,
449 uint32_t *p_dest, const uint32_t *p_src )
451 uint32_t p_wtxt[ 4 ]; /* Working cyphertext */
453 unsigned int i_round, t;
455 for( t = 0; t < 4; t++ )
457 /* FIXME: are there any endianness issues here? */
458 p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
462 for( i_round = 0; i_round < (AES_KEY_COUNT - 1); i_round++ )
464 for( t = 0; t < 4; t++ )
466 p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
469 for( t = 0; t < 4; t++ )
471 p_wtxt[ t ] = p_tmp[ t ]
472 ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - i_round ][ t ];
476 /* Final round (9) */
477 for( t = 0; t < 4; t++ )
479 p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
480 p_dest[ t ] ^= p_aes->pp_dec_keys[ 0 ][ t ];
484 /*****************************************************************************
485 * InitShuffle: initialise a shuffle structure
486 *****************************************************************************
487 * This function initialises tables in the p_shuffle structure that will be
488 * used later by DoShuffle. The only external parameter is p_sys_key.
489 *****************************************************************************/
490 static void InitShuffle( struct shuffle_s *p_shuffle, uint32_t *p_sys_key,
493 char p_secret1[] = "Tv!*";
494 static const char p_secret2[] = "____v8rhvsaAvOKM____FfUH%798=[;."
495 "____f8677680a634____ba87fnOIf)(*";
498 p_shuffle->i_version = i_version;
500 /* Fill p_commands using the key and a secret seed */
501 for( i = 0; i < 20; i++ )
507 AddMD5( &md5, (const uint8_t *)p_sys_key, 16 );
508 AddMD5( &md5, (const uint8_t *)p_secret1, 4 );
513 REVERSE( md5.p_digest, 1 );
514 i_hash = ((int32_t)U32_AT(md5.p_digest)) % 1024;
516 p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
519 /* Fill p_bordel with completely meaningless initial values. */
520 memcpy( p_shuffle->p_bordel, p_secret2, 64 );
521 for( i = 0; i < 4; i++ )
523 p_shuffle->p_bordel[ 4 * i ] = U32_AT(p_sys_key + i);
524 REVERSE( p_shuffle->p_bordel + 4 * i + 1, 3 );
528 /*****************************************************************************
529 * DoShuffle: shuffle buffer
530 *****************************************************************************
531 * This is so ugly and uses so many MD5 checksums that it is most certainly
532 * one-way, though why it needs to be so complicated is beyond me.
533 *****************************************************************************/
534 static void DoShuffle( struct shuffle_s *p_shuffle,
535 uint32_t *p_buffer, uint32_t i_size )
538 uint32_t p_big_bordel[ 16 ];
539 uint32_t *p_bordel = p_shuffle->p_bordel;
542 static const uint32_t p_secret3[] =
544 0xAAAAAAAA, 0x01757700, 0x00554580, 0x01724500, 0x00424580,
545 0x01427700, 0x00000080, 0xC1D59D01, 0x80144981, 0x815C8901,
546 0x80544981, 0x81D45D01, 0x00000080, 0x81A3BB03, 0x00A2AA82,
547 0x01A3BB03, 0x0022A282, 0x813BA202, 0x00000080, 0x6D575737,
548 0x4A5275A5, 0x6D525725, 0x4A5254A5, 0x6B725437, 0x00000080,
549 0xD5DDB938, 0x5455A092, 0x5D95A013, 0x4415A192, 0xC5DD393A,
550 0x00000080, 0x55555555
552 static const uint32_t i_secret3 = sizeof(p_secret3)/sizeof(p_secret3[0]);
554 static const char p_secret4[] =
555 "pbclevtug (p) Nccyr Pbzchgre, Vap. Nyy Evtugf Erfreirq.";
556 static const uint32_t i_secret4 = sizeof(p_secret4)/sizeof(p_secret4[0]); /* It include the terminal '\0' */
558 /* Using the MD5 hash of a memory block is probably not one-way enough
559 * for the iTunes people. This function randomises p_bordel depending on
560 * the values in p_commands to make things even more messy in p_bordel. */
561 for( i = 0; i < 20; i++ )
563 uint8_t i_command, i_index;
565 if( !p_shuffle->p_commands[ i ] )
570 i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
571 i_index = p_shuffle->p_commands[ i ] & 0xff;
576 p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
577 + p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
580 p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
583 p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
586 p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
591 if( p_shuffle->i_version == 0x01000300 )
593 DoExtShuffle( p_bordel );
596 /* Convert our newly randomised p_bordel to big endianness and take
599 for( i = 0; i < 16; i++ )
601 p_big_bordel[ i ] = U32_AT(p_bordel + i);
603 AddMD5( &md5, (const uint8_t *)p_big_bordel, 64 );
604 if( p_shuffle->i_version == 0x01000300 )
606 uint32_t p_tmp3[i_secret3];
607 char p_tmp4[i_secret4];
609 memcpy( p_tmp3, p_secret3, sizeof(p_secret3) );
610 REVERSE( p_tmp3, i_secret3 );
612 #define ROT13(c) (((c)>='A'&&(c)<='Z')?(((c)-'A'+13)%26)+'A':\
613 ((c)>='a'&&(c)<='z')?(((c)-'a'+13)%26)+'a':c)
614 for( uint32_t i = 0; i < i_secret4; i++ )
615 p_tmp4[i] = ROT13( p_secret4[i] );
618 AddMD5( &md5, (const uint8_t *)p_tmp3, sizeof(p_secret3) );
619 AddMD5( &md5, (const uint8_t *)p_tmp4, i_secret4 );
623 /* XOR our buffer with the computed checksum */
624 for( i = 0; i < i_size; i++ )
626 p_buffer[ i ] ^= md5.p_digest[ i ];
630 /*****************************************************************************
631 * DoExtShuffle: extended shuffle
632 *****************************************************************************
633 * This is even uglier.
634 *****************************************************************************/
635 static void DoExtShuffle( uint32_t * p_bordel )
639 i_ret = FirstPass( p_bordel );
641 SecondPass( p_bordel, i_ret );
643 ThirdPass( p_bordel );
645 FourthPass( p_bordel );
648 static uint32_t FirstPass( uint32_t * p_bordel )
650 uint32_t i, i_cmd, i_ret = 5;
652 TinyShuffle1( p_bordel );
658 p_bordel[ 1 ] += 0x10000000;
659 p_bordel[ 3 ] += 0x12777;
661 if( (p_bordel[ 10 ] & 1) && i_ret )
664 p_bordel[ 1 ] -= p_bordel[ 2 ];
665 p_bordel[ 11 ] += p_bordel[ 12 ];
669 if( (p_bordel[ 1 ] + p_bordel[ 2 ]) >= 0x7D0 )
671 switch( ((p_bordel[ 3 ] ^ 0x567F) >> 2) & 7 )
674 for( i = 0; i < 3; i++ )
676 if( p_bordel[ i + 10 ] > 0x4E20 )
678 p_bordel[ i + 1 ] += p_bordel[ i + 2 ];
683 p_bordel[ 1 ] -= p_bordel[ 2 ];
686 p_bordel[ 11 ] += p_bordel[ 12 ];
689 p_bordel[ 3 ] ^= p_bordel[ 4 ];
692 p_bordel[ 13 ] &= p_bordel[ 14 ];
695 p_bordel[ 0 ] |= p_bordel[ 1 ];
707 for( i = 0, i_cmd = 0; i < 16; i++ )
709 if( p_bordel[ i ] < p_bordel[ i_cmd ] )
715 if( i_ret && i_cmd != 5 )
723 p_bordel[ 8 ] &= p_bordel[ 6 ] >> 1;
727 for( i = 0; i < 3; i++ )
730 if( p_bordel[ 11 ] & 5 )
732 p_bordel[ 8 ] += p_bordel[ 9 ];
742 i_cmd = (p_bordel[ 15 ] + 0x93) >> 3;
743 if( p_bordel[ 15 ] & 0x100 )
752 while( p_bordel[ 11 ] & 1 )
754 p_bordel[ 11 ] >>= 1;
759 p_bordel[ 14 ] -= 0x19FE;
771 i_cmd = ((p_bordel[ 3 ] + p_bordel[ 4 ] + 10) >> 1) - p_bordel[ 4 ];
779 p_bordel[ 14 ] >>= 1;
788 p_bordel[ 15 ] &= 0x55;
791 p_bordel[ 2 ] &= 0xB62FC;
797 TinyShuffle2( p_bordel );
802 static void SecondPass( uint32_t * p_bordel, uint32_t i_tmp )
804 uint32_t i, i_cmd, i_jc = 5;
806 TinyShuffle3( p_bordel );
808 for( i = 0, i_cmd = 0; i < 16; i++ )
810 if( p_bordel[ i ] > p_bordel[ i_cmd ] )
819 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
825 if( (p_bordel[ 9 ] & 0x7777) == 0x3333 )
832 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
841 p_bordel[ 1 ] -= p_bordel[ 5 ];
842 for( i = 0; i < 3; i++ )
844 switch( p_bordel[ 1 ] & 3 )
853 p_bordel[ 13 ] &= 0xFEFEFEF7;
856 p_bordel[ 8 ] |= 0x80080011;
868 p_bordel[ 15 ] ^= 0x18547EFF;
874 switch( ( p_bordel[ 12 ] + p_bordel[ 13 ] + p_bordel[ 6 ] ) % 5 )
894 i = 3; /* Restart the whole loop */
899 TinyShuffle4( p_bordel );
903 TinyShuffle5( p_bordel );
905 switch( ( p_bordel[ 2 ] * 2 + 15 ) % 5 )
908 if( ( p_bordel[ 3 ] + i_tmp ) <=
909 ( p_bordel[ 1 ] + p_bordel[ 15 ] ) )
915 p_bordel[ 10 ] -= 0x13;
922 if( !( p_bordel[ 2 ] & 1 ) || i_jc == 0 )
928 p_bordel[ 2 ] += 0x13;
932 p_bordel[ 2 ] &= 0x10076000;
935 static void ThirdPass( uint32_t * p_bordel )
939 i_cmd = ((p_bordel[ 7 ] + p_bordel[ 14 ] + 10) >> 1) - p_bordel[ 14 ];
950 p_bordel[ i_cmd + 3 ] &= 0x5EDE36B;
951 p_bordel[ 5 ] += p_bordel[ 8 ];
952 p_bordel[ 4 ] += p_bordel[ 7 ];
953 p_bordel[ 3 ] += p_bordel[ 6 ];
954 p_bordel[ 2 ] += p_bordel[ 5 ];
957 p_bordel[ 1 ] += p_bordel[ 4 ];
958 p_bordel[ 0 ] += p_bordel[ 3 ];
959 TinyShuffle6( p_bordel );
962 if( (p_bordel[ 11 ] & p_bordel[ 2 ]) > 0x211B )
971 p_bordel[ 9 ] ^= p_bordel[ 2 ];
974 p_bordel[ 2 ] ^= (p_bordel[ 1 ] & p_bordel[ 13 ]);
977 p_bordel[ 0 ] -= p_bordel[ 11 ] & p_bordel[ 15 ];
980 p_bordel[ 6 ] >>= (p_bordel[ 14 ] & 3);
984 SWAP( p_bordel[ 0 ], p_bordel[ 10 ] );
986 TinyShuffle6( p_bordel );
991 static void FourthPass( uint32_t * p_bordel )
995 TinyShuffle7( p_bordel );
997 switch( p_bordel[ 5 ] % 5)
1003 p_bordel[ 11 ] ^= (p_bordel[ 3 ] + p_bordel[ 6 ] + p_bordel[ 8 ]);
1006 for( i = 4; i < 15 && (p_bordel[ i ] & 5) == 0; i++ )
1008 SWAP( p_bordel[ i ], p_bordel[ 15 - i ] );
1012 p_bordel[ 12 ] -= 1;
1013 p_bordel[ 13 ] += 1;
1014 p_bordel[ 2 ] -= 0x64;
1015 p_bordel[ 3 ] += 0x64;
1016 TinyShuffle8( p_bordel );
1020 for( i = 0, j = 0; i < 16; i++ )
1022 if( p_bordel[ i ] > p_bordel[ j ] )
1028 switch( p_bordel[ j ] % 100 )
1031 SWAP( p_bordel[ 0 ], p_bordel[ j ] );
1034 p_bordel[ 1 ] >>= 1;
1035 p_bordel[ 2 ] <<= 1;
1036 p_bordel[ 14 ] >>= 3;
1037 p_bordel[ 15 ] <<= 4;
1040 p_bordel[ j ] += p_bordel[ 13 ];
1043 p_bordel[ 1 ] += 0x20E;
1044 p_bordel[ 5 ] += 0x223D;
1045 p_bordel[ 13 ] -= 0x576;
1046 p_bordel[ 15 ] += 0x576;
1049 p_bordel[ 2 ] -= 0x64;
1050 p_bordel[ 3 ] += 0x64;
1051 p_bordel[ 12 ] -= 1;
1052 p_bordel[ 13 ] += 1;
1056 p_bordel[ j ] += p_bordel[ 13 ];
1060 TinyShuffle8( p_bordel );
1063 /*****************************************************************************
1064 * TinyShuffle[12345678]: tiny shuffle subroutines
1065 *****************************************************************************
1066 * These standalone functions are little helpers for the shuffling process.
1067 *****************************************************************************/
1068 static void TinyShuffle1( uint32_t * p_bordel )
1070 uint32_t i_cmd = (p_bordel[ 5 ] + 10) >> 2;
1072 if( p_bordel[ 5 ] > 0x7D0 )
1086 if( p_bordel[ 4 ] & 5 )
1088 p_bordel[ 1 ] ^= 0x4D;
1092 p_bordel[ 12 ] += 5;
1097 static void TinyShuffle2( uint32_t * p_bordel )
1101 for( i = 0, j = 0; i < 16; i++ )
1103 if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) )
1111 for( ; j < 15; j++ )
1113 p_bordel[ j ] += p_bordel[ j + 1 ];
1118 p_bordel[ 2 ] &= 0xB62FC;
1122 static void TinyShuffle3( uint32_t * p_bordel )
1124 uint32_t i_cmd = p_bordel[ 6 ] + 0x194B;
1126 if( p_bordel[ 6 ] > 0x2710 )
1134 p_bordel[ 3 ] += 0x19FE;
1137 p_bordel[ 7 ] -= p_bordel[ 3 ] >> 2;
1140 p_bordel[ 5 ] ^= 0x248A;
1145 static void TinyShuffle4( uint32_t * p_bordel )
1149 for( i = 0, j = 0; i < 16; i++ )
1151 if( p_bordel[ i ] < p_bordel[ j ] )
1157 if( (p_bordel[ j ] % (j + 1)) > 10 )
1160 p_bordel[ 2 ] += 0x13;
1161 p_bordel[ 12 ] += 1;
1165 static void TinyShuffle5( uint32_t * p_bordel )
1169 p_bordel[ 2 ] &= 0x7F3F;
1171 for( i = 0; i < 5; i++ )
1173 switch( ( p_bordel[ 2 ] + 10 + i ) % 5 )
1176 p_bordel[ 12 ] &= p_bordel[ 2 ];
1179 p_bordel[ 3 ] ^= p_bordel[ 15 ];
1182 p_bordel[ 15 ] += 0x576;
1185 p_bordel[ 7 ] -= 0x2D;
1188 p_bordel[ 1 ] <<= 1;
1194 static void TinyShuffle6( uint32_t * p_bordel )
1198 for( i = 0; i < 8; i++ )
1200 j = p_bordel[ 3 ] & 0x7514 ? 5 : 7;
1201 SWAP( p_bordel[ i ], p_bordel[ i + j ] );
1205 static void TinyShuffle7( uint32_t * p_bordel )
1209 i = (((p_bordel[ 9 ] + p_bordel[ 15 ] + 12) >> 2) - p_bordel[ 4 ]) & 7;
1213 SWAP( p_bordel[ i ], p_bordel[ i + 3 ] );
1216 SWAP( p_bordel[ 1 ], p_bordel[ 10 ] );
1219 static void TinyShuffle8( uint32_t * p_bordel )
1223 i = (p_bordel[ 0 ] & p_bordel[ 6 ]) & 0xF;
1225 switch( p_bordel[ i ] % 1000 )
1228 if( (p_bordel[ i ] & 0x777) > (p_bordel[ 7 ] & 0x5555) )
1230 p_bordel[ i ] ^= p_bordel[ 5 ] & p_bordel[ 3 ];
1234 p_bordel[ 15 ] &= 0x5555;
1237 p_bordel[ i ] ^= p_bordel[ 15 ];
1240 SWAP( p_bordel[ 0 ], p_bordel[ 3 ] );
1241 SWAP( p_bordel[ 1 ], p_bordel[ 6 ] );
1242 SWAP( p_bordel[ 3 ], p_bordel[ 6 ] );
1243 SWAP( p_bordel[ 4 ], p_bordel[ 9 ] );
1244 SWAP( p_bordel[ 5 ], p_bordel[ 8 ] );
1245 SWAP( p_bordel[ 6 ], p_bordel[ 7 ] );
1246 SWAP( p_bordel[ 13 ], p_bordel[ 14 ] );
1249 p_bordel[ i ] += p_bordel[ 1 ] ^ 0x80080011;
1250 p_bordel[ i ] += p_bordel[ 2 ] ^ 0xBEEFDEAD;
1251 p_bordel[ i ] += p_bordel[ 3 ] ^ 0x8765F444;
1252 p_bordel[ i ] += p_bordel[ 4 ] ^ 0x78145326;
1255 p_bordel[ 12 ] -= p_bordel[ i ];
1256 p_bordel[ 13 ] += p_bordel[ i ];
1259 p_bordel[ i ] += p_bordel[ 1 ];
1260 p_bordel[ i ] -= p_bordel[ 7 ];
1261 p_bordel[ i ] -= p_bordel[ 8 ];
1262 p_bordel[ i ] += p_bordel[ 9 ];
1263 p_bordel[ i ] += p_bordel[ 13 ];
1267 p_bordel[ i + 1 ] >>= 1;
1268 p_bordel[ i + 2 ] <<= 4;
1269 p_bordel[ i + 3 ] >>= 3;
1272 p_bordel[ 1 ] += 0x20E;
1273 p_bordel[ 5 ] += 0x223D;
1274 p_bordel[ 13 ] -= 0x576;
1275 p_bordel[ 15 ] += 0x576;
1278 if( (p_bordel[ i ] ^ 0x8765F441) < 0x2710 )
1280 SWAP( p_bordel[ 0 ], p_bordel[ 1 ] );
1284 SWAP( p_bordel[ 1 ], p_bordel[ 11 ] );
1290 /*****************************************************************************
1291 * GetSystemKey: get the system key
1292 *****************************************************************************
1293 * Compute the system key from various system information, see HashSystemInfo.
1294 *****************************************************************************/
1295 static int GetSystemKey( uint32_t *p_sys_key, bool b_ipod )
1297 static const char p_secret5[ 8 ] = "YuaFlafu";
1298 static const char p_secret6[ 8 ] = "zPif98ga";
1301 uint32_t p_system_hash[ 4 ];
1303 /* Compute the MD5 hash of our system info */
1304 if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) ||
1305 ( b_ipod && GetiPodID( &i_ipod_id ) ) )
1310 /* Combine our system info hash with additional secret data. The resulting
1311 * MD5 hash will be our system key. */
1313 AddMD5( &md5, (const uint8_t*)p_secret5, 8 );
1317 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1318 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1319 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1320 AddMD5( &md5, (const uint8_t *)p_secret6, 8 );
1324 i_ipod_id = U64_AT(&i_ipod_id);
1325 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1326 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1327 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1332 memcpy( p_sys_key, md5.p_digest, 16 );
1338 # define DRMS_DIRNAME "drms"
1340 # define DRMS_DIRNAME ".drms"
1343 /*****************************************************************************
1344 * WriteUserKey: write the user key to hard disk
1345 *****************************************************************************
1346 * Write the user key to the hard disk so that it can be reused later or used
1347 * on operating systems other than Win32.
1348 *****************************************************************************/
1349 static int WriteUserKey( void *_p_drms, uint32_t *p_user_key )
1351 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1354 char psz_path[ PATH_MAX ];
1356 snprintf( psz_path, PATH_MAX - 1,
1357 "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
1359 #if defined( WIN32 )
1360 if( !mkdir( psz_path ) || errno == EEXIST )
1362 if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
1365 snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d",
1366 p_drms->psz_homedir, p_drms->i_user, p_drms->i_key );
1368 file = utf8_fopen( psz_path, "wb" );
1371 i_ret = fwrite( p_user_key, sizeof(uint32_t),
1372 4, file ) == 4 ? 0 : -1;
1380 /*****************************************************************************
1381 * ReadUserKey: read the user key from hard disk
1382 *****************************************************************************
1383 * Retrieve the user key from the hard disk if available.
1384 *****************************************************************************/
1385 static int ReadUserKey( void *_p_drms, uint32_t *p_user_key )
1387 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1390 char psz_path[ PATH_MAX ];
1392 snprintf( psz_path, PATH_MAX - 1,
1393 "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir,
1394 p_drms->i_user, p_drms->i_key );
1396 file = utf8_fopen( psz_path, "rb" );
1399 i_ret = fread( p_user_key, sizeof(uint32_t),
1400 4, file ) == 4 ? 0 : -1;
1407 /*****************************************************************************
1408 * GetUserKey: get the user key
1409 *****************************************************************************
1410 * Retrieve the user key from the hard disk if available, otherwise generate
1411 * it from the system key. If the key could be successfully generated, write
1412 * it to the hard disk for future use.
1413 *****************************************************************************/
1414 static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
1416 static const char p_secret7[] = "mUfnpognadfgf873";
1417 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1419 struct shuffle_s shuffle;
1421 uint32_t *p_sci_data = NULL;
1422 uint32_t i_user, i_key;
1423 uint32_t p_sys_key[ 4 ];
1424 uint32_t i_sci_size = 0, i_blocks, i_remaining;
1425 uint32_t *p_sci0, *p_sci1, *p_buffer;
1426 uint32_t p_sci_key[ 4 ];
1430 if( ReadUserKey( p_drms, p_user_key ) == 0 )
1432 REVERSE( p_user_key, 4 );
1436 psz_ipod = getenv( "IPOD" );
1438 if( GetSystemKey( p_sys_key, psz_ipod ? true : false ) )
1443 if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
1448 /* Phase 1: unscramble the SCI data using the system key and shuffle
1449 * it using DoShuffle(). */
1451 /* Skip the first 4 bytes (some sort of header). Decrypt the rest. */
1452 i_blocks = (i_sci_size - 4) / 16;
1453 i_remaining = (i_sci_size - 4) - (i_blocks * 16);
1454 p_buffer = p_sci_data + 1;
1456 /* Decrypt and shuffle our data at the same time */
1457 InitAES( &aes, p_sys_key );
1458 REVERSE( p_sys_key, 4 );
1459 REVERSE( p_sci_data, 1 );
1460 InitShuffle( &shuffle, p_sys_key, p_sci_data[ 0 ] );
1462 memcpy( p_sci_key, p_secret7, 16 );
1463 REVERSE( p_sci_key, 4 );
1467 uint32_t p_tmp[ 4 ];
1469 REVERSE( p_buffer, 4 );
1470 DecryptAES( &aes, p_tmp, p_buffer );
1471 BlockXOR( p_tmp, p_sci_key, p_tmp );
1473 /* Use the previous scrambled data as the key for next block */
1474 memcpy( p_sci_key, p_buffer, 16 );
1476 /* Shuffle the decrypted data using a custom routine */
1477 DoShuffle( &shuffle, p_tmp, 4 );
1479 /* Copy this block back to p_buffer */
1480 memcpy( p_buffer, p_tmp, 16 );
1485 if( i_remaining >= 4 )
1487 REVERSE( p_buffer, i_remaining / 4 );
1488 DoShuffle( &shuffle, p_buffer, i_remaining / 4 );
1491 /* Phase 2: look for the user key in the generated data. I must admit I
1492 * do not understand what is going on here, because it almost
1493 * looks like we are browsing data that makes sense, even though
1494 * the DoShuffle() part made it completely meaningless. */
1497 REVERSE( p_sci_data + 5, 1 );
1498 i = U32_AT( p_sci_data + 5 );
1499 i_sci_size -= 22 * sizeof(uint32_t);
1500 p_sci1 = p_sci_data + 22;
1503 while( i_sci_size >= 20 && i > 0 )
1505 if( p_sci0 == NULL )
1507 i_sci_size -= 18 * sizeof(uint32_t);
1508 if( i_sci_size < 20 )
1514 REVERSE( p_sci1 + 17, 1 );
1515 y = U32_AT( p_sci1 + 17 );
1526 i_user = U32_AT( p_sci0 );
1527 i_key = U32_AT( p_sci1 );
1528 REVERSE( &i_user, 1 );
1529 REVERSE( &i_key, 1 );
1530 if( i_user == p_drms->i_user && ( ( i_key == p_drms->i_key ) ||
1531 ( !p_drms->i_key && ( p_sci1 == (p_sci0 + 18) ) ) ) )
1533 memcpy( p_user_key, p_sci1 + 1, 16 );
1534 REVERSE( p_sci1 + 1, 4 );
1535 WriteUserKey( p_drms, p_sci1 + 1 );
1542 i_sci_size -= 5 * sizeof(uint32_t);
1550 /*****************************************************************************
1551 * GetSCIData: get SCI data from "SC Info.sidb"
1552 *****************************************************************************
1553 * Read SCI data from "\Apple Computer\iTunes\SC Info\SC Info.sidb"
1554 *****************************************************************************/
1555 static int GetSCIData( char *psz_ipod, uint32_t **pp_sci,
1556 uint32_t *pi_sci_size )
1559 char *psz_path = NULL;
1560 char p_tmp[ 4 * PATH_MAX ];
1563 if( psz_ipod == NULL )
1566 const char *SCIfile =
1567 "\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb";
1568 strncpy(p_tmp, config_GetConfDir(), sizeof(p_tmp -1));
1569 if( strlen( p_tmp ) + strlen( SCIfile ) >= PATH_MAX )
1571 strcat(p_tmp, SCIfile);
1572 p_tmp[sizeof( p_tmp ) - 1] = '\0';
1578 #define ISCINFO "iSCInfo"
1579 if( strstr( psz_ipod, ISCINFO ) == NULL )
1581 snprintf( p_tmp, sizeof(p_tmp) - 1,
1582 "%s/iPod_Control/iTunes/" ISCINFO "2", psz_ipod );
1587 psz_path = psz_ipod;
1591 if( psz_path == NULL )
1596 file = utf8_fopen( psz_path, "rb" );
1601 if( !fstat( fileno( file ), &st ) && st.st_size >= 4 )
1603 *pp_sci = malloc( st.st_size );
1604 if( *pp_sci != NULL )
1606 if( fread( *pp_sci, 1, st.st_size,
1607 file ) == (size_t)st.st_size )
1609 *pi_sci_size = st.st_size;
1614 free( (void *)*pp_sci );
1626 /*****************************************************************************
1627 * HashSystemInfo: hash system information
1628 *****************************************************************************
1629 * This function computes the MD5 hash of the C: hard drive serial number,
1630 * BIOS version, CPU type and Windows version.
1631 *****************************************************************************/
1632 static int HashSystemInfo( uint32_t *p_system_hash )
1644 static const LPCTSTR p_reg_keys[ 3 ][ 2 ] =
1647 _T("HARDWARE\\DESCRIPTION\\System"),
1648 _T("SystemBiosVersion")
1652 _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
1653 _T("ProcessorNameString")
1657 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
1664 AddMD5( &md5, "cache-control", 13 );
1665 AddMD5( &md5, "Ethernet", 8 );
1667 GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
1668 NULL, NULL, NULL, 0 );
1669 AddMD5( &md5, (const uint8_t *)&i_serial, 4 );
1671 for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
1673 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
1674 0, KEY_READ, &i_key ) != ERROR_SUCCESS )
1679 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1680 NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
1682 RegCloseKey( i_key );
1686 p_reg_buf = malloc( i_size );
1688 if( p_reg_buf != NULL )
1690 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1691 NULL, NULL, p_reg_buf,
1692 &i_size ) == ERROR_SUCCESS )
1694 AddMD5( &md5, (const uint8_t *)p_reg_buf, i_size );
1700 RegCloseKey( i_key );
1709 memcpy( p_system_hash, md5.p_digest, 16 );
1714 /*****************************************************************************
1715 * GetiPodID: Get iPod ID
1716 *****************************************************************************
1717 * This function gets the iPod ID.
1718 *****************************************************************************/
1719 static int GetiPodID( int64_t *p_ipod_id )
1723 #define PROD_NAME "iPod"
1724 #define VENDOR_NAME "Apple Computer, Inc."
1726 char *psz_ipod_id = getenv( "IPODID" );
1727 if( psz_ipod_id != NULL )
1729 *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
1737 io_iterator_t iterator;
1738 CFMutableDictionaryRef match_dic;
1739 CFMutableDictionaryRef smatch_dic;
1741 if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
1743 smatch_dic = IOServiceMatching( "IOFireWireUnit" );
1744 match_dic = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
1745 &kCFTypeDictionaryKeyCallBacks,
1746 &kCFTypeDictionaryValueCallBacks );
1748 if( smatch_dic != NULL && match_dic != NULL )
1750 CFDictionarySetValue( smatch_dic,
1751 CFSTR("FireWire Vendor Name"),
1752 CFSTR(VENDOR_NAME) );
1753 CFDictionarySetValue( smatch_dic,
1754 CFSTR("FireWire Product Name"),
1757 CFDictionarySetValue( match_dic,
1758 CFSTR(kIOPropertyMatchKey),
1761 if( IOServiceGetMatchingServices( port, match_dic,
1762 &iterator ) == KERN_SUCCESS )
1764 while( ( device = IOIteratorNext( iterator ) ) != 0 )
1766 value = IORegistryEntryCreateCFProperty( device,
1767 CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );
1771 if( CFGetTypeID( value ) == CFNumberGetTypeID() )
1774 CFNumberGetValue( (CFNumberRef)value,
1775 kCFNumberLongLongType,
1777 *p_ipod_id = i_ipod_id;
1784 IOObjectRelease( device );
1789 IOObjectRelease( iterator );
1791 CFRelease( match_dic );
1794 mach_port_deallocate( mach_task_self(), port );
1797 #elif defined (HAVE_SYSFS_LIBSYSFS_H)
1798 struct sysfs_bus *bus = NULL;
1799 struct dlist *devlist = NULL;
1800 struct dlist *attributes = NULL;
1801 struct sysfs_device *curdev = NULL;
1802 struct sysfs_attribute *curattr = NULL;
1804 bus = sysfs_open_bus( "ieee1394" );
1807 devlist = sysfs_get_bus_devices( bus );
1808 if( devlist != NULL )
1810 dlist_for_each_data( devlist, curdev, struct sysfs_device )
1812 attributes = sysfs_get_device_attributes( curdev );
1813 if( attributes != NULL )
1815 dlist_for_each_data( attributes, curattr,
1816 struct sysfs_attribute )
1818 if( ( strcmp( curattr->name, "model_name" ) == 0 ) &&
1819 ( strncmp( curattr->value, PROD_NAME,
1820 sizeof(PROD_NAME) ) == 0 ) )
1822 *p_ipod_id = strtoll( curdev->name, NULL, 16 );
1833 sysfs_close_bus( bus );
1840 #else /* !defined( UNDER_CE ) */
1842 void *drms_alloc( const char *psz_homedir ){ return NULL; }
1843 void drms_free( void *a ){}
1844 void drms_decrypt( void *a, uint32_t *b, uint32_t c, uint32_t *k ){}
1845 void drms_get_p_key( void *p_drms, uint32_t *p_key ){}
1846 int drms_init( void *a, uint32_t b, uint8_t *c, uint32_t d ){ return -1; }
1848 #endif /* defined( UNDER_CE ) */