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 "TargetConditionals.h"
61 #ifndef TARGET_OS_IPHONE
62 #define HAVE_MACOS_IOKIT
66 #ifdef HAVE_MACOS_IOKIT
67 # include <mach/mach.h>
68 # include <IOKit/IOKitLib.h>
69 # include <CoreFoundation/CFNumber.h>
73 #include "drmstables.h"
75 #if !defined( UNDER_CE )
76 /*****************************************************************************
77 * aes_s: AES keys structure
78 *****************************************************************************
79 * This structure stores a set of keys usable for encryption and decryption
80 * with the AES/Rijndael algorithm.
81 *****************************************************************************/
84 uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
85 uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
88 #define Digest DigestMD5
90 /*****************************************************************************
91 * shuffle_s: shuffle structure
92 *****************************************************************************
93 * This structure stores the static information needed to shuffle data using
95 *****************************************************************************/
99 uint32_t p_commands[ 20 ];
100 uint32_t p_bordel[ 16 ];
103 #define SWAP( a, b ) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
105 /*****************************************************************************
106 * drms_s: DRMS structure
107 *****************************************************************************
108 * This structure stores the static information needed to decrypt DRMS data.
109 *****************************************************************************/
114 uint8_t p_iviv[ 16 ];
120 char psz_homedir[ PATH_MAX ];
123 /*****************************************************************************
125 *****************************************************************************/
126 static void InitAES ( struct aes_s *, uint32_t * );
127 static void DecryptAES ( struct aes_s *, uint32_t *, const uint32_t * );
129 static void InitShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
130 static void DoShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
132 static uint32_t FirstPass ( uint32_t * );
133 static void SecondPass ( uint32_t *, uint32_t );
134 static void ThirdPass ( uint32_t * );
135 static void FourthPass ( uint32_t * );
136 static void TinyShuffle1 ( uint32_t * );
137 static void TinyShuffle2 ( uint32_t * );
138 static void TinyShuffle3 ( uint32_t * );
139 static void TinyShuffle4 ( uint32_t * );
140 static void TinyShuffle5 ( uint32_t * );
141 static void TinyShuffle6 ( uint32_t * );
142 static void TinyShuffle7 ( uint32_t * );
143 static void TinyShuffle8 ( uint32_t * );
144 static void DoExtShuffle ( uint32_t * );
146 static int GetSystemKey ( uint32_t *, bool );
147 static int WriteUserKey ( void *, uint32_t * );
148 static int ReadUserKey ( void *, uint32_t * );
149 static int GetUserKey ( void *, uint32_t * );
151 static int GetSCIData ( char *, uint32_t **, uint32_t * );
152 static int HashSystemInfo ( uint32_t * );
153 static int GetiPodID ( int64_t * );
155 #ifdef WORDS_BIGENDIAN
156 /*****************************************************************************
157 * Reverse: reverse byte order
158 *****************************************************************************/
159 static inline void Reverse( uint32_t *p_buffer, int n )
163 for( i = 0; i < n; i++ )
165 p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
168 # define REVERSE( p, n ) Reverse( p, n )
170 # define REVERSE( p, n )
173 /*****************************************************************************
174 * BlockXOR: XOR two 128 bit blocks
175 *****************************************************************************/
176 static inline void BlockXOR( uint32_t *p_dest, uint32_t *p_s1, uint32_t *p_s2 )
180 for( i = 0; i < 4; i++ )
182 p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
186 /*****************************************************************************
187 * drms_alloc: allocate a DRMS structure
188 *****************************************************************************/
189 void *drms_alloc( const char *psz_homedir )
191 struct drms_s *p_drms;
193 p_drms = calloc( 1, sizeof(struct drms_s) );
197 strncpy( p_drms->psz_homedir, psz_homedir, PATH_MAX );
198 p_drms->psz_homedir[ PATH_MAX - 1 ] = '\0';
200 return (void *)p_drms;
203 /*****************************************************************************
204 * drms_free: free a previously allocated DRMS structure
205 *****************************************************************************/
206 void drms_free( void *_p_drms )
208 struct drms_s *p_drms = (struct drms_s *)_p_drms;
210 free( (void *)p_drms->p_name );
214 /*****************************************************************************
215 * drms_decrypt: unscramble a chunk of data
216 *****************************************************************************/
217 void drms_decrypt( void *_p_drms, uint32_t *p_buffer, uint32_t i_bytes, uint32_t *p_key )
219 struct drms_s *p_drms = (struct drms_s *)_p_drms;
220 uint32_t p_key_buf[ 4 ];
221 unsigned int i_blocks;
223 /* AES is a block cypher, round down the byte count */
224 i_blocks = i_bytes / 16;
225 i_bytes = i_blocks * 16;
227 /* Initialise the key */
231 memcpy( p_key, p_drms->p_key, 16 );
239 REVERSE( p_buffer, 4 );
240 DecryptAES( &p_drms->aes, p_tmp, p_buffer );
241 BlockXOR( p_tmp, p_key, p_tmp );
243 /* Use the previous scrambled data as the key for next block */
244 memcpy( p_key, p_buffer, 16 );
246 /* Copy unscrambled data back to the buffer */
247 memcpy( p_buffer, p_tmp, 16 );
248 REVERSE( p_buffer, 4 );
254 /*****************************************************************************
255 * drms_get_p_key: copy the p_key into user buffer
256 ****************************************************************************/
257 void drms_get_p_key( void *_p_drms, uint32_t *p_key )
259 struct drms_s *p_drms = (struct drms_s *)_p_drms;
261 memcpy( p_key, p_drms->p_key, 16 );
264 /*****************************************************************************
265 * drms_init: initialise a DRMS structure
266 *****************************************************************************
270 * -2: invalid argument
271 * -3: could not get system key
272 * -4: could not get SCI data
273 * -5: no user key found in SCI data
274 * -6: invalid user key
275 *****************************************************************************/
276 int drms_init( void *_p_drms, uint32_t i_type,
277 uint8_t *p_info, uint32_t i_len )
279 struct drms_s *p_drms = (struct drms_s *)_p_drms;
285 if( i_len < sizeof(p_drms->i_user) )
291 p_drms->i_user = U32_AT( p_info );
295 if( i_len < sizeof(p_drms->i_key) )
301 p_drms->i_key = U32_AT( p_info );
305 if( i_len < sizeof(p_drms->p_key) )
311 memcpy( p_drms->p_iviv, p_info, 16 );
315 p_drms->p_name = (uint8_t*) strdup( (char *)p_info );
317 if( p_drms->p_name == NULL )
325 uint32_t p_priv[ 64 ];
335 AddMD5( &md5, p_drms->p_name, strlen( (char *)p_drms->p_name ) );
336 AddMD5( &md5, p_drms->p_iviv, 16 );
339 if( p_drms->i_user == 0 && p_drms->i_key == 0 )
341 static const char p_secret[] = "tr1-th3n.y00_by3";
342 memcpy( p_drms->p_key, p_secret, 16 );
343 REVERSE( p_drms->p_key, 4 );
347 i_ret = GetUserKey( p_drms, p_drms->p_key );
354 InitAES( &p_drms->aes, p_drms->p_key );
356 memcpy( p_priv, p_info, 64 );
357 memcpy( p_drms->p_key, md5.buf, 16 );
358 drms_decrypt( p_drms, p_priv, 64, NULL );
359 REVERSE( p_priv, 64 );
361 if( p_priv[ 0 ] != 0x6e757469 ) /* itun */
367 InitAES( &p_drms->aes, p_priv + 6 );
368 memcpy( p_drms->p_key, p_priv + 12, 16 );
370 free( (void *)p_drms->p_name );
371 p_drms->p_name = NULL;
379 /* The following functions are local */
381 /*****************************************************************************
382 * InitAES: initialise AES/Rijndael encryption/decryption tables
383 *****************************************************************************
384 * The Advanced Encryption Standard (AES) is described in RFC 3268
385 *****************************************************************************/
386 static void InitAES( struct aes_s *p_aes, uint32_t *p_key )
389 uint32_t i_key, i_seed;
391 memset( p_aes->pp_enc_keys[1], 0, 16 );
392 memcpy( p_aes->pp_enc_keys[0], p_key, 16 );
394 /* Generate the key tables */
395 i_seed = p_aes->pp_enc_keys[ 0 ][ 3 ];
397 for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
401 i_seed = AES_ROR( i_seed, 8 );
403 j = p_aes_table[ i_key ];
405 j ^= p_aes_encrypt[ (i_seed >> 24) & 0xff ]
406 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 16) & 0xff ], 8 )
407 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 8) & 0xff ], 16 )
408 ^ AES_ROR( p_aes_encrypt[ i_seed & 0xff ], 24 );
410 j ^= p_aes->pp_enc_keys[ i_key ][ 0 ];
411 p_aes->pp_enc_keys[ i_key + 1 ][ 0 ] = j;
412 j ^= p_aes->pp_enc_keys[ i_key ][ 1 ];
413 p_aes->pp_enc_keys[ i_key + 1 ][ 1 ] = j;
414 j ^= p_aes->pp_enc_keys[ i_key ][ 2 ];
415 p_aes->pp_enc_keys[ i_key + 1 ][ 2 ] = j;
416 j ^= p_aes->pp_enc_keys[ i_key ][ 3 ];
417 p_aes->pp_enc_keys[ i_key + 1 ][ 3 ] = j;
422 memcpy( p_aes->pp_dec_keys[ 0 ],
423 p_aes->pp_enc_keys[ 0 ], 16 );
425 for( i = 1; i < AES_KEY_COUNT; i++ )
427 for( t = 0; t < 4; t++ )
429 uint32_t j, k, l, m, n;
431 j = p_aes->pp_enc_keys[ i ][ t ];
433 k = (((j >> 7) & 0x01010101) * 27) ^ ((j & 0xff7f7f7f) << 1);
434 l = (((k >> 7) & 0x01010101) * 27) ^ ((k & 0xff7f7f7f) << 1);
435 m = (((l >> 7) & 0x01010101) * 27) ^ ((l & 0xff7f7f7f) << 1);
439 n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
441 p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
446 /*****************************************************************************
447 * DecryptAES: decrypt an AES/Rijndael 128 bit block
448 *****************************************************************************/
449 static void DecryptAES( struct aes_s *p_aes,
450 uint32_t *p_dest, const uint32_t *p_src )
452 uint32_t p_wtxt[ 4 ]; /* Working cyphertext */
454 unsigned int i_round, t;
456 for( t = 0; t < 4; t++ )
458 /* FIXME: are there any endianness issues here? */
459 p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
463 for( i_round = 0; i_round < (AES_KEY_COUNT - 1); i_round++ )
465 for( t = 0; t < 4; t++ )
467 p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
470 for( t = 0; t < 4; t++ )
472 p_wtxt[ t ] = p_tmp[ t ]
473 ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - i_round ][ t ];
477 /* Final round (9) */
478 for( t = 0; t < 4; t++ )
480 p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
481 p_dest[ t ] ^= p_aes->pp_dec_keys[ 0 ][ t ];
485 /*****************************************************************************
486 * InitShuffle: initialise a shuffle structure
487 *****************************************************************************
488 * This function initialises tables in the p_shuffle structure that will be
489 * used later by DoShuffle. The only external parameter is p_sys_key.
490 *****************************************************************************/
491 static void InitShuffle( struct shuffle_s *p_shuffle, uint32_t *p_sys_key,
494 char p_secret1[] = "Tv!*";
495 static const char p_secret2[] = "____v8rhvsaAvOKM____FfUH%798=[;."
496 "____f8677680a634____ba87fnOIf)(*";
499 p_shuffle->i_version = i_version;
501 /* Fill p_commands using the key and a secret seed */
502 for( i = 0; i < 20; i++ )
508 AddMD5( &md5, (const uint8_t *)p_sys_key, 16 );
509 AddMD5( &md5, (const uint8_t *)p_secret1, 4 );
514 REVERSE( (void *)md5.buf, 1 ); /* FIXME */
515 i_hash = ((int32_t)U32_AT(md5.buf)) % 1024;
517 p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
520 /* Fill p_bordel with completely meaningless initial values. */
521 memcpy( p_shuffle->p_bordel, p_secret2, 64 );
522 for( i = 0; i < 4; i++ )
524 p_shuffle->p_bordel[ 4 * i ] = U32_AT(p_sys_key + i);
525 REVERSE( p_shuffle->p_bordel + 4 * i + 1, 3 );
529 /*****************************************************************************
530 * DoShuffle: shuffle buffer
531 *****************************************************************************
532 * This is so ugly and uses so many MD5 checksums that it is most certainly
533 * one-way, though why it needs to be so complicated is beyond me.
534 *****************************************************************************/
535 static void DoShuffle( struct shuffle_s *p_shuffle,
536 uint32_t *p_buffer, uint32_t i_size )
539 uint32_t p_big_bordel[ 16 ];
540 uint32_t *p_bordel = p_shuffle->p_bordel;
543 static const uint32_t p_secret3[] =
545 0xAAAAAAAA, 0x01757700, 0x00554580, 0x01724500, 0x00424580,
546 0x01427700, 0x00000080, 0xC1D59D01, 0x80144981, 0x815C8901,
547 0x80544981, 0x81D45D01, 0x00000080, 0x81A3BB03, 0x00A2AA82,
548 0x01A3BB03, 0x0022A282, 0x813BA202, 0x00000080, 0x6D575737,
549 0x4A5275A5, 0x6D525725, 0x4A5254A5, 0x6B725437, 0x00000080,
550 0xD5DDB938, 0x5455A092, 0x5D95A013, 0x4415A192, 0xC5DD393A,
551 0x00000080, 0x55555555
553 static const uint32_t i_secret3 = sizeof(p_secret3)/sizeof(p_secret3[0]);
555 static const char p_secret4[] =
556 "pbclevtug (p) Nccyr Pbzchgre, Vap. Nyy Evtugf Erfreirq.";
557 static const uint32_t i_secret4 = sizeof(p_secret4)/sizeof(p_secret4[0]); /* It include the terminal '\0' */
559 /* Using the MD5 hash of a memory block is probably not one-way enough
560 * for the iTunes people. This function randomises p_bordel depending on
561 * the values in p_commands to make things even more messy in p_bordel. */
562 for( i = 0; i < 20; i++ )
564 uint8_t i_command, i_index;
566 if( !p_shuffle->p_commands[ i ] )
571 i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
572 i_index = p_shuffle->p_commands[ i ] & 0xff;
577 p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
578 + p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
581 p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
584 p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
587 p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
592 if( p_shuffle->i_version == 0x01000300 )
594 DoExtShuffle( p_bordel );
597 /* Convert our newly randomised p_bordel to big endianness and take
600 for( i = 0; i < 16; i++ )
602 p_big_bordel[ i ] = U32_AT(p_bordel + i);
604 AddMD5( &md5, (const uint8_t *)p_big_bordel, 64 );
605 if( p_shuffle->i_version == 0x01000300 )
607 uint32_t p_tmp3[i_secret3];
608 char p_tmp4[i_secret4];
610 memcpy( p_tmp3, p_secret3, sizeof(p_secret3) );
611 REVERSE( p_tmp3, i_secret3 );
613 #define ROT13(c) (((c)>='A'&&(c)<='Z')?(((c)-'A'+13)%26)+'A':\
614 ((c)>='a'&&(c)<='z')?(((c)-'a'+13)%26)+'a':c)
615 for( uint32_t i = 0; i < i_secret4; i++ )
616 p_tmp4[i] = ROT13( p_secret4[i] );
619 AddMD5( &md5, (const uint8_t *)p_tmp3, sizeof(p_secret3) );
620 AddMD5( &md5, (const uint8_t *)p_tmp4, i_secret4 );
624 /* XOR our buffer with the computed checksum */
625 for( i = 0; i < i_size; i++ )
627 p_buffer[ i ] ^= U32_AT(md5.buf + (4 * i));
631 /*****************************************************************************
632 * DoExtShuffle: extended shuffle
633 *****************************************************************************
634 * This is even uglier.
635 *****************************************************************************/
636 static void DoExtShuffle( uint32_t * p_bordel )
640 i_ret = FirstPass( p_bordel );
642 SecondPass( p_bordel, i_ret );
644 ThirdPass( p_bordel );
646 FourthPass( p_bordel );
649 static uint32_t FirstPass( uint32_t * p_bordel )
651 uint32_t i, i_cmd, i_ret = 5;
653 TinyShuffle1( p_bordel );
659 p_bordel[ 1 ] += 0x10000000;
660 p_bordel[ 3 ] += 0x12777;
662 if( (p_bordel[ 10 ] & 1) && i_ret )
665 p_bordel[ 1 ] -= p_bordel[ 2 ];
666 p_bordel[ 11 ] += p_bordel[ 12 ];
670 if( (p_bordel[ 1 ] + p_bordel[ 2 ]) >= 0x7D0 )
672 switch( ((p_bordel[ 3 ] ^ 0x567F) >> 2) & 7 )
675 for( i = 0; i < 3; i++ )
677 if( p_bordel[ i + 10 ] > 0x4E20 )
679 p_bordel[ i + 1 ] += p_bordel[ i + 2 ];
684 p_bordel[ 1 ] -= p_bordel[ 2 ];
687 p_bordel[ 11 ] += p_bordel[ 12 ];
690 p_bordel[ 3 ] ^= p_bordel[ 4 ];
693 p_bordel[ 13 ] &= p_bordel[ 14 ];
696 p_bordel[ 0 ] |= p_bordel[ 1 ];
708 for( i = 0, i_cmd = 0; i < 16; i++ )
710 if( p_bordel[ i ] < p_bordel[ i_cmd ] )
716 if( i_ret && i_cmd != 5 )
724 p_bordel[ 8 ] &= p_bordel[ 6 ] >> 1;
728 for( i = 0; i < 3; i++ )
731 if( p_bordel[ 11 ] & 5 )
733 p_bordel[ 8 ] += p_bordel[ 9 ];
743 i_cmd = (p_bordel[ 15 ] + 0x93) >> 3;
744 if( p_bordel[ 15 ] & 0x100 )
753 while( p_bordel[ 11 ] & 1 )
755 p_bordel[ 11 ] >>= 1;
760 p_bordel[ 14 ] -= 0x19FE;
772 i_cmd = ((p_bordel[ 3 ] + p_bordel[ 4 ] + 10) >> 1) - p_bordel[ 4 ];
780 p_bordel[ 14 ] >>= 1;
789 p_bordel[ 15 ] &= 0x55;
792 p_bordel[ 2 ] &= 0xB62FC;
798 TinyShuffle2( p_bordel );
803 static void SecondPass( uint32_t * p_bordel, uint32_t i_tmp )
805 uint32_t i, i_cmd, i_jc = 5;
807 TinyShuffle3( p_bordel );
809 for( i = 0, i_cmd = 0; i < 16; i++ )
811 if( p_bordel[ i ] > p_bordel[ i_cmd ] )
820 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
826 if( (p_bordel[ 9 ] & 0x7777) == 0x3333 )
833 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
842 p_bordel[ 1 ] -= p_bordel[ 5 ];
843 for( i = 0; i < 3; i++ )
845 switch( p_bordel[ 1 ] & 3 )
854 p_bordel[ 13 ] &= 0xFEFEFEF7;
857 p_bordel[ 8 ] |= 0x80080011;
869 p_bordel[ 15 ] ^= 0x18547EFF;
875 switch( ( p_bordel[ 12 ] + p_bordel[ 13 ] + p_bordel[ 6 ] ) % 5 )
895 i = 3; /* Restart the whole loop */
900 TinyShuffle4( p_bordel );
904 TinyShuffle5( p_bordel );
906 switch( ( p_bordel[ 2 ] * 2 + 15 ) % 5 )
909 if( ( p_bordel[ 3 ] + i_tmp ) <=
910 ( p_bordel[ 1 ] + p_bordel[ 15 ] ) )
916 p_bordel[ 10 ] -= 0x13;
923 if( !( p_bordel[ 2 ] & 1 ) || i_jc == 0 )
929 p_bordel[ 2 ] += 0x13;
933 p_bordel[ 2 ] &= 0x10076000;
936 static void ThirdPass( uint32_t * p_bordel )
940 i_cmd = ((p_bordel[ 7 ] + p_bordel[ 14 ] + 10) >> 1) - p_bordel[ 14 ];
951 p_bordel[ i_cmd + 3 ] &= 0x5EDE36B;
952 p_bordel[ 5 ] += p_bordel[ 8 ];
953 p_bordel[ 4 ] += p_bordel[ 7 ];
954 p_bordel[ 3 ] += p_bordel[ 6 ];
955 p_bordel[ 2 ] += p_bordel[ 5 ];
958 p_bordel[ 1 ] += p_bordel[ 4 ];
959 p_bordel[ 0 ] += p_bordel[ 3 ];
960 TinyShuffle6( p_bordel );
963 if( (p_bordel[ 11 ] & p_bordel[ 2 ]) > 0x211B )
972 p_bordel[ 9 ] ^= p_bordel[ 2 ];
975 p_bordel[ 2 ] ^= (p_bordel[ 1 ] & p_bordel[ 13 ]);
978 p_bordel[ 0 ] -= p_bordel[ 11 ] & p_bordel[ 15 ];
981 p_bordel[ 6 ] >>= (p_bordel[ 14 ] & 3);
985 SWAP( p_bordel[ 0 ], p_bordel[ 10 ] );
987 TinyShuffle6( p_bordel );
992 static void FourthPass( uint32_t * p_bordel )
996 TinyShuffle7( p_bordel );
998 switch( p_bordel[ 5 ] % 5)
1004 p_bordel[ 11 ] ^= (p_bordel[ 3 ] + p_bordel[ 6 ] + p_bordel[ 8 ]);
1007 for( i = 4; i < 15 && (p_bordel[ i ] & 5) == 0; i++ )
1009 SWAP( p_bordel[ i ], p_bordel[ 15 - i ] );
1013 p_bordel[ 12 ] -= 1;
1014 p_bordel[ 13 ] += 1;
1015 p_bordel[ 2 ] -= 0x64;
1016 p_bordel[ 3 ] += 0x64;
1017 TinyShuffle8( p_bordel );
1021 for( i = 0, j = 0; i < 16; i++ )
1023 if( p_bordel[ i ] > p_bordel[ j ] )
1029 switch( p_bordel[ j ] % 100 )
1032 SWAP( p_bordel[ 0 ], p_bordel[ j ] );
1035 p_bordel[ 1 ] >>= 1;
1036 p_bordel[ 2 ] <<= 1;
1037 p_bordel[ 14 ] >>= 3;
1038 p_bordel[ 15 ] <<= 4;
1041 p_bordel[ j ] += p_bordel[ 13 ];
1044 p_bordel[ 1 ] += 0x20E;
1045 p_bordel[ 5 ] += 0x223D;
1046 p_bordel[ 13 ] -= 0x576;
1047 p_bordel[ 15 ] += 0x576;
1050 p_bordel[ 2 ] -= 0x64;
1051 p_bordel[ 3 ] += 0x64;
1052 p_bordel[ 12 ] -= 1;
1053 p_bordel[ 13 ] += 1;
1057 p_bordel[ j ] += p_bordel[ 13 ];
1061 TinyShuffle8( p_bordel );
1064 /*****************************************************************************
1065 * TinyShuffle[12345678]: tiny shuffle subroutines
1066 *****************************************************************************
1067 * These standalone functions are little helpers for the shuffling process.
1068 *****************************************************************************/
1069 static void TinyShuffle1( uint32_t * p_bordel )
1071 uint32_t i_cmd = (p_bordel[ 5 ] + 10) >> 2;
1073 if( p_bordel[ 5 ] > 0x7D0 )
1087 if( p_bordel[ 4 ] & 5 )
1089 p_bordel[ 1 ] ^= 0x4D;
1093 p_bordel[ 12 ] += 5;
1098 static void TinyShuffle2( uint32_t * p_bordel )
1102 for( i = 0, j = 0; i < 16; i++ )
1104 if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) )
1112 for( ; j < 15; j++ )
1114 p_bordel[ j ] += p_bordel[ j + 1 ];
1119 p_bordel[ 2 ] &= 0xB62FC;
1123 static void TinyShuffle3( uint32_t * p_bordel )
1125 uint32_t i_cmd = p_bordel[ 6 ] + 0x194B;
1127 if( p_bordel[ 6 ] > 0x2710 )
1135 p_bordel[ 3 ] += 0x19FE;
1138 p_bordel[ 7 ] -= p_bordel[ 3 ] >> 2;
1141 p_bordel[ 5 ] ^= 0x248A;
1146 static void TinyShuffle4( uint32_t * p_bordel )
1150 for( i = 0, j = 0; i < 16; i++ )
1152 if( p_bordel[ i ] < p_bordel[ j ] )
1158 if( (p_bordel[ j ] % (j + 1)) > 10 )
1161 p_bordel[ 2 ] += 0x13;
1162 p_bordel[ 12 ] += 1;
1166 static void TinyShuffle5( uint32_t * p_bordel )
1170 p_bordel[ 2 ] &= 0x7F3F;
1172 for( i = 0; i < 5; i++ )
1174 switch( ( p_bordel[ 2 ] + 10 + i ) % 5 )
1177 p_bordel[ 12 ] &= p_bordel[ 2 ];
1180 p_bordel[ 3 ] ^= p_bordel[ 15 ];
1183 p_bordel[ 15 ] += 0x576;
1186 p_bordel[ 7 ] -= 0x2D;
1189 p_bordel[ 1 ] <<= 1;
1195 static void TinyShuffle6( uint32_t * p_bordel )
1199 for( i = 0; i < 8; i++ )
1201 j = p_bordel[ 3 ] & 0x7514 ? 5 : 7;
1202 SWAP( p_bordel[ i ], p_bordel[ i + j ] );
1206 static void TinyShuffle7( uint32_t * p_bordel )
1210 i = (((p_bordel[ 9 ] + p_bordel[ 15 ] + 12) >> 2) - p_bordel[ 4 ]) & 7;
1214 SWAP( p_bordel[ i ], p_bordel[ i + 3 ] );
1217 SWAP( p_bordel[ 1 ], p_bordel[ 10 ] );
1220 static void TinyShuffle8( uint32_t * p_bordel )
1224 i = (p_bordel[ 0 ] & p_bordel[ 6 ]) & 0xF;
1226 switch( p_bordel[ i ] % 1000 )
1229 if( (p_bordel[ i ] & 0x777) > (p_bordel[ 7 ] & 0x5555) )
1231 p_bordel[ i ] ^= p_bordel[ 5 ] & p_bordel[ 3 ];
1235 p_bordel[ 15 ] &= 0x5555;
1238 p_bordel[ i ] ^= p_bordel[ 15 ];
1241 SWAP( p_bordel[ 0 ], p_bordel[ 3 ] );
1242 SWAP( p_bordel[ 1 ], p_bordel[ 6 ] );
1243 SWAP( p_bordel[ 3 ], p_bordel[ 6 ] );
1244 SWAP( p_bordel[ 4 ], p_bordel[ 9 ] );
1245 SWAP( p_bordel[ 5 ], p_bordel[ 8 ] );
1246 SWAP( p_bordel[ 6 ], p_bordel[ 7 ] );
1247 SWAP( p_bordel[ 13 ], p_bordel[ 14 ] );
1250 p_bordel[ i ] += p_bordel[ 1 ] ^ 0x80080011;
1251 p_bordel[ i ] += p_bordel[ 2 ] ^ 0xBEEFDEAD;
1252 p_bordel[ i ] += p_bordel[ 3 ] ^ 0x8765F444;
1253 p_bordel[ i ] += p_bordel[ 4 ] ^ 0x78145326;
1256 p_bordel[ 12 ] -= p_bordel[ i ];
1257 p_bordel[ 13 ] += p_bordel[ i ];
1260 p_bordel[ i ] += p_bordel[ 1 ];
1261 p_bordel[ i ] -= p_bordel[ 7 ];
1262 p_bordel[ i ] -= p_bordel[ 8 ];
1263 p_bordel[ i ] += p_bordel[ 9 ];
1264 p_bordel[ i ] += p_bordel[ 13 ];
1268 p_bordel[ i + 1 ] >>= 1;
1269 p_bordel[ i + 2 ] <<= 4;
1270 p_bordel[ i + 3 ] >>= 3;
1273 p_bordel[ 1 ] += 0x20E;
1274 p_bordel[ 5 ] += 0x223D;
1275 p_bordel[ 13 ] -= 0x576;
1276 p_bordel[ 15 ] += 0x576;
1279 if( (p_bordel[ i ] ^ 0x8765F441) < 0x2710 )
1281 SWAP( p_bordel[ 0 ], p_bordel[ 1 ] );
1285 SWAP( p_bordel[ 1 ], p_bordel[ 11 ] );
1291 /*****************************************************************************
1292 * GetSystemKey: get the system key
1293 *****************************************************************************
1294 * Compute the system key from various system information, see HashSystemInfo.
1295 *****************************************************************************/
1296 static int GetSystemKey( uint32_t *p_sys_key, bool b_ipod )
1298 static const char p_secret5[ 8 ] = "YuaFlafu";
1299 static const char p_secret6[ 8 ] = "zPif98ga";
1302 uint32_t p_system_hash[ 4 ];
1304 /* Compute the MD5 hash of our system info */
1305 if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) ||
1306 ( b_ipod && GetiPodID( &i_ipod_id ) ) )
1311 /* Combine our system info hash with additional secret data. The resulting
1312 * MD5 hash will be our system key. */
1314 AddMD5( &md5, (const uint8_t*)p_secret5, 8 );
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_system_hash, 6 );
1321 AddMD5( &md5, (const uint8_t *)p_secret6, 8 );
1325 i_ipod_id = U64_AT(&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) );
1328 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1333 memcpy( p_sys_key, md5.buf, 16 );
1339 # define DRMS_DIRNAME "drms"
1341 # define DRMS_DIRNAME ".drms"
1344 /*****************************************************************************
1345 * WriteUserKey: write the user key to hard disk
1346 *****************************************************************************
1347 * Write the user key to the hard disk so that it can be reused later or used
1348 * on operating systems other than Win32.
1349 *****************************************************************************/
1350 static int WriteUserKey( void *_p_drms, uint32_t *p_user_key )
1352 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1355 char psz_path[ PATH_MAX ];
1357 snprintf( psz_path, PATH_MAX - 1,
1358 "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
1360 #if defined( WIN32 )
1361 if( !mkdir( psz_path ) || errno == EEXIST )
1363 if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
1366 snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d",
1367 p_drms->psz_homedir, p_drms->i_user, p_drms->i_key );
1369 file = vlc_fopen( psz_path, "wb" );
1372 i_ret = fwrite( p_user_key, sizeof(uint32_t),
1373 4, file ) == 4 ? 0 : -1;
1381 /*****************************************************************************
1382 * ReadUserKey: read the user key from hard disk
1383 *****************************************************************************
1384 * Retrieve the user key from the hard disk if available.
1385 *****************************************************************************/
1386 static int ReadUserKey( void *_p_drms, uint32_t *p_user_key )
1388 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1391 char psz_path[ PATH_MAX ];
1393 snprintf( psz_path, PATH_MAX - 1,
1394 "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir,
1395 p_drms->i_user, p_drms->i_key );
1397 file = vlc_fopen( psz_path, "rb" );
1400 i_ret = fread( p_user_key, sizeof(uint32_t),
1401 4, file ) == 4 ? 0 : -1;
1408 /*****************************************************************************
1409 * GetUserKey: get the user key
1410 *****************************************************************************
1411 * Retrieve the user key from the hard disk if available, otherwise generate
1412 * it from the system key. If the key could be successfully generated, write
1413 * it to the hard disk for future use.
1414 *****************************************************************************/
1415 static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
1417 static const char p_secret7[] = "mUfnpognadfgf873";
1418 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1420 struct shuffle_s shuffle;
1422 uint32_t *p_sci_data = NULL;
1423 uint32_t i_user, i_key;
1424 uint32_t p_sys_key[ 4 ];
1425 uint32_t i_sci_size = 0, i_blocks, i_remaining;
1426 uint32_t *p_sci0, *p_sci1, *p_buffer;
1427 uint32_t p_sci_key[ 4 ];
1431 if( ReadUserKey( p_drms, p_user_key ) == 0 )
1433 REVERSE( p_user_key, 4 );
1437 psz_ipod = getenv( "IPOD" );
1439 if( GetSystemKey( p_sys_key, psz_ipod ? true : false ) )
1444 if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
1449 /* Phase 1: unscramble the SCI data using the system key and shuffle
1450 * it using DoShuffle(). */
1452 /* Skip the first 4 bytes (some sort of header). Decrypt the rest. */
1453 i_blocks = (i_sci_size - 4) / 16;
1454 i_remaining = (i_sci_size - 4) - (i_blocks * 16);
1455 p_buffer = p_sci_data + 1;
1457 /* Decrypt and shuffle our data at the same time */
1458 InitAES( &aes, p_sys_key );
1459 REVERSE( p_sys_key, 4 );
1460 REVERSE( p_sci_data, 1 );
1461 InitShuffle( &shuffle, p_sys_key, p_sci_data[ 0 ] );
1463 memcpy( p_sci_key, p_secret7, 16 );
1464 REVERSE( p_sci_key, 4 );
1468 uint32_t p_tmp[ 4 ];
1470 REVERSE( p_buffer, 4 );
1471 DecryptAES( &aes, p_tmp, p_buffer );
1472 BlockXOR( p_tmp, p_sci_key, p_tmp );
1474 /* Use the previous scrambled data as the key for next block */
1475 memcpy( p_sci_key, p_buffer, 16 );
1477 /* Shuffle the decrypted data using a custom routine */
1478 DoShuffle( &shuffle, p_tmp, 4 );
1480 /* Copy this block back to p_buffer */
1481 memcpy( p_buffer, p_tmp, 16 );
1486 if( i_remaining >= 4 )
1488 REVERSE( p_buffer, i_remaining / 4 );
1489 DoShuffle( &shuffle, p_buffer, i_remaining / 4 );
1492 /* Phase 2: look for the user key in the generated data. I must admit I
1493 * do not understand what is going on here, because it almost
1494 * looks like we are browsing data that makes sense, even though
1495 * the DoShuffle() part made it completely meaningless. */
1498 REVERSE( p_sci_data + 5, 1 );
1499 i = U32_AT( p_sci_data + 5 );
1500 i_sci_size -= 22 * sizeof(uint32_t);
1501 p_sci1 = p_sci_data + 22;
1504 while( i_sci_size >= 20 && i > 0 )
1506 if( p_sci0 == NULL )
1508 i_sci_size -= 18 * sizeof(uint32_t);
1509 if( i_sci_size < 20 )
1515 REVERSE( p_sci1 + 17, 1 );
1516 y = U32_AT( p_sci1 + 17 );
1527 i_user = U32_AT( p_sci0 );
1528 i_key = U32_AT( p_sci1 );
1529 REVERSE( &i_user, 1 );
1530 REVERSE( &i_key, 1 );
1531 if( i_user == p_drms->i_user && ( ( i_key == p_drms->i_key ) ||
1532 ( !p_drms->i_key && ( p_sci1 == (p_sci0 + 18) ) ) ) )
1534 memcpy( p_user_key, p_sci1 + 1, 16 );
1535 REVERSE( p_sci1 + 1, 4 );
1536 WriteUserKey( p_drms, p_sci1 + 1 );
1543 i_sci_size -= 5 * sizeof(uint32_t);
1551 /*****************************************************************************
1552 * GetSCIData: get SCI data from "SC Info.sidb"
1553 *****************************************************************************
1554 * Read SCI data from "\Apple Computer\iTunes\SC Info\SC Info.sidb"
1555 *****************************************************************************/
1556 static int GetSCIData( char *psz_ipod, uint32_t **pp_sci,
1557 uint32_t *pi_sci_size )
1560 char *psz_path = NULL;
1561 char p_tmp[ 4 * PATH_MAX ];
1564 if( psz_ipod == NULL )
1567 const char *SCIfile =
1568 "\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb";
1569 strncpy( p_tmp, config_GetConfDir(), sizeof(p_tmp) - 1 );
1570 if( strlen( p_tmp ) + strlen( SCIfile ) >= PATH_MAX )
1572 strcat(p_tmp, SCIfile);
1573 p_tmp[sizeof( p_tmp ) - 1] = '\0';
1579 #define ISCINFO "iSCInfo"
1580 if( strstr( psz_ipod, ISCINFO ) == NULL )
1582 snprintf( p_tmp, sizeof(p_tmp) - 1,
1583 "%s/iPod_Control/iTunes/" ISCINFO "2", psz_ipod );
1588 psz_path = psz_ipod;
1592 if( psz_path == NULL )
1597 file = vlc_fopen( psz_path, "rb" );
1602 if( !fstat( fileno( file ), &st ) && st.st_size >= 4 )
1604 *pp_sci = malloc( st.st_size );
1605 if( *pp_sci != NULL )
1607 if( fread( *pp_sci, 1, st.st_size,
1608 file ) == (size_t)st.st_size )
1610 *pi_sci_size = st.st_size;
1615 free( (void *)*pp_sci );
1627 /*****************************************************************************
1628 * HashSystemInfo: hash system information
1629 *****************************************************************************
1630 * This function computes the MD5 hash of the C: hard drive serial number,
1631 * BIOS version, CPU type and Windows version.
1632 *****************************************************************************/
1633 static int HashSystemInfo( uint32_t *p_system_hash )
1645 static const LPCTSTR p_reg_keys[ 3 ][ 2 ] =
1648 _T("HARDWARE\\DESCRIPTION\\System"),
1649 _T("SystemBiosVersion")
1653 _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
1654 _T("ProcessorNameString")
1658 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
1665 AddMD5( &md5, "cache-control", 13 );
1666 AddMD5( &md5, "Ethernet", 8 );
1668 GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
1669 NULL, NULL, NULL, 0 );
1670 AddMD5( &md5, (const uint8_t *)&i_serial, 4 );
1672 for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
1674 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
1675 0, KEY_READ, &i_key ) != ERROR_SUCCESS )
1680 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1681 NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
1683 RegCloseKey( i_key );
1687 p_reg_buf = malloc( i_size );
1689 if( p_reg_buf != NULL )
1691 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1692 NULL, NULL, p_reg_buf,
1693 &i_size ) == ERROR_SUCCESS )
1695 AddMD5( &md5, (const uint8_t *)p_reg_buf, i_size );
1701 RegCloseKey( i_key );
1710 memcpy( p_system_hash, md5.buf, 16 );
1715 /*****************************************************************************
1716 * GetiPodID: Get iPod ID
1717 *****************************************************************************
1718 * This function gets the iPod ID.
1719 *****************************************************************************/
1720 static int GetiPodID( int64_t *p_ipod_id )
1724 #define PROD_NAME "iPod"
1725 #define VENDOR_NAME "Apple Computer, Inc."
1727 char *psz_ipod_id = getenv( "IPODID" );
1728 if( psz_ipod_id != NULL )
1730 *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
1734 #ifdef HAVE_MACOS_IOKIT
1738 io_iterator_t iterator;
1739 CFMutableDictionaryRef match_dic;
1740 CFMutableDictionaryRef smatch_dic;
1742 if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
1744 smatch_dic = IOServiceMatching( "IOFireWireUnit" );
1745 match_dic = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
1746 &kCFTypeDictionaryKeyCallBacks,
1747 &kCFTypeDictionaryValueCallBacks );
1749 if( smatch_dic != NULL && match_dic != NULL )
1751 CFDictionarySetValue( smatch_dic,
1752 CFSTR("FireWire Vendor Name"),
1753 CFSTR(VENDOR_NAME) );
1754 CFDictionarySetValue( smatch_dic,
1755 CFSTR("FireWire Product Name"),
1758 CFDictionarySetValue( match_dic,
1759 CFSTR(kIOPropertyMatchKey),
1761 CFRelease( smatch_dic );
1763 if( IOServiceGetMatchingServices( port, match_dic,
1764 &iterator ) == KERN_SUCCESS )
1766 while( ( device = IOIteratorNext( iterator ) ) != 0 )
1768 value = IORegistryEntryCreateCFProperty( device,
1769 CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );
1773 if( CFGetTypeID( value ) == CFNumberGetTypeID() )
1776 CFNumberGetValue( (CFNumberRef)value,
1777 kCFNumberLongLongType,
1779 *p_ipod_id = i_ipod_id;
1786 IOObjectRelease( device );
1791 IOObjectRelease( iterator );
1797 CFRelease( match_dic );
1799 CFRelease( smatch_dic );
1803 mach_port_deallocate( mach_task_self(), port );
1810 #else /* !defined( UNDER_CE ) */
1812 void *drms_alloc( const char *psz_homedir ){ return NULL; }
1813 void drms_free( void *a ){}
1814 void drms_decrypt( void *a, uint32_t *b, uint32_t c, uint32_t *k ){}
1815 void drms_get_p_key( void *p_drms, uint32_t *p_key ){}
1816 int drms_init( void *a, uint32_t b, uint8_t *c, uint32_t d ){ return -1; }
1818 #endif /* defined( UNDER_CE ) */