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 *****************************************************************************/
30 # include <vlc_common.h>
33 # include <vlc_charset.h>
47 # if !defined( UNDER_CE )
55 #ifdef HAVE_SYS_STAT_H
56 # include <sys/stat.h>
58 #ifdef HAVE_SYS_TYPES_H
59 # include <sys/types.h>
62 /* In Solaris (and perhaps others) PATH_MAX is in limits.h. */
66 # include <mach/mach.h>
67 # include <IOKit/IOKitLib.h>
68 # include <CoreFoundation/CFNumber.h>
71 #ifdef HAVE_SYSFS_LIBSYSFS_H
72 # include <sysfs/libsysfs.h>
76 #include "drmstables.h"
78 #if !defined( UNDER_CE )
79 /*****************************************************************************
80 * aes_s: AES keys structure
81 *****************************************************************************
82 * This structure stores a set of keys usable for encryption and decryption
83 * with the AES/Rijndael algorithm.
84 *****************************************************************************/
87 uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
88 uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
92 # define Digest DigestMD5
94 /*****************************************************************************
95 * md5_s: MD5 message structure
96 *****************************************************************************
97 * This structure stores the static information needed to compute an MD5
98 * hash. It has an extra data buffer to allow non-aligned writes.
99 *****************************************************************************/
102 uint64_t i_bits; /* Total written bits */
103 uint32_t p_digest[4]; /* The MD5 digest */
104 uint32_t p_data[16]; /* Buffer to cache non-aligned writes */
108 /*****************************************************************************
109 * shuffle_s: shuffle structure
110 *****************************************************************************
111 * This structure stores the static information needed to shuffle data using
112 * a custom algorithm.
113 *****************************************************************************/
117 uint32_t p_commands[ 20 ];
118 uint32_t p_bordel[ 16 ];
121 #define SWAP( a, b ) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
123 /*****************************************************************************
124 * drms_s: DRMS structure
125 *****************************************************************************
126 * This structure stores the static information needed to decrypt DRMS data.
127 *****************************************************************************/
132 uint8_t p_iviv[ 16 ];
138 char psz_homedir[ PATH_MAX ];
141 /*****************************************************************************
143 *****************************************************************************/
144 static void InitAES ( struct aes_s *, uint32_t * );
145 static void DecryptAES ( struct aes_s *, uint32_t *, const uint32_t * );
148 static void InitMD5 ( struct md5_s * );
149 static void AddMD5 ( struct md5_s *, const uint8_t *, uint32_t );
150 static void EndMD5 ( struct md5_s * );
151 static void Digest ( struct md5_s *, uint32_t * );
154 static void InitShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
155 static void DoShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
157 static uint32_t FirstPass ( uint32_t * );
158 static void SecondPass ( uint32_t *, uint32_t );
159 static void ThirdPass ( uint32_t * );
160 static void FourthPass ( uint32_t * );
161 static void TinyShuffle1 ( uint32_t * );
162 static void TinyShuffle2 ( uint32_t * );
163 static void TinyShuffle3 ( uint32_t * );
164 static void TinyShuffle4 ( uint32_t * );
165 static void TinyShuffle5 ( uint32_t * );
166 static void TinyShuffle6 ( uint32_t * );
167 static void TinyShuffle7 ( uint32_t * );
168 static void TinyShuffle8 ( uint32_t * );
169 static void DoExtShuffle ( uint32_t * );
171 static int GetSystemKey ( uint32_t *, bool );
172 static int WriteUserKey ( void *, uint32_t * );
173 static int ReadUserKey ( void *, uint32_t * );
174 static int GetUserKey ( void *, uint32_t * );
176 static int GetSCIData ( char *, uint32_t **, uint32_t * );
177 static int HashSystemInfo ( uint32_t * );
178 static int GetiPodID ( int64_t * );
180 #ifdef WORDS_BIGENDIAN
181 /*****************************************************************************
182 * Reverse: reverse byte order
183 *****************************************************************************/
184 static inline void Reverse( uint32_t *p_buffer, int n )
188 for( i = 0; i < n; i++ )
190 p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
193 # define REVERSE( p, n ) Reverse( p, n )
195 # define REVERSE( p, n )
198 /*****************************************************************************
199 * BlockXOR: XOR two 128 bit blocks
200 *****************************************************************************/
201 static inline void BlockXOR( uint32_t *p_dest, uint32_t *p_s1, uint32_t *p_s2 )
205 for( i = 0; i < 4; i++ )
207 p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
211 /*****************************************************************************
212 * drms_alloc: allocate a DRMS structure
213 *****************************************************************************/
214 void *drms_alloc( const char *psz_homedir )
216 struct drms_s *p_drms;
218 p_drms = calloc( 1, sizeof(struct drms_s) );
222 strncpy( p_drms->psz_homedir, psz_homedir, PATH_MAX );
223 p_drms->psz_homedir[ PATH_MAX - 1 ] = '\0';
225 return (void *)p_drms;
228 /*****************************************************************************
229 * drms_free: free a previously allocated DRMS structure
230 *****************************************************************************/
231 void drms_free( void *_p_drms )
233 struct drms_s *p_drms = (struct drms_s *)_p_drms;
235 free( (void *)p_drms->p_name );
239 /*****************************************************************************
240 * drms_decrypt: unscramble a chunk of data
241 *****************************************************************************/
242 void drms_decrypt( void *_p_drms, uint32_t *p_buffer, uint32_t i_bytes, uint32_t *p_key )
244 struct drms_s *p_drms = (struct drms_s *)_p_drms;
245 uint32_t p_key_buf[ 4 ];
246 unsigned int i_blocks;
248 /* AES is a block cypher, round down the byte count */
249 i_blocks = i_bytes / 16;
250 i_bytes = i_blocks * 16;
252 /* Initialise the key */
256 memcpy( p_key, p_drms->p_key, 16 );
264 REVERSE( p_buffer, 4 );
265 DecryptAES( &p_drms->aes, p_tmp, p_buffer );
266 BlockXOR( p_tmp, p_key, p_tmp );
268 /* Use the previous scrambled data as the key for next block */
269 memcpy( p_key, p_buffer, 16 );
271 /* Copy unscrambled data back to the buffer */
272 memcpy( p_buffer, p_tmp, 16 );
273 REVERSE( p_buffer, 4 );
279 /*****************************************************************************
280 * drms_get_p_key: copy the p_key into user buffer
281 ****************************************************************************/
282 void drms_get_p_key( void *_p_drms, uint32_t *p_key )
284 struct drms_s *p_drms = (struct drms_s *)_p_drms;
286 memcpy( p_key, p_drms->p_key, 16 );
289 /*****************************************************************************
290 * drms_init: initialise a DRMS structure
291 *****************************************************************************
295 * -2: invalid argument
296 * -3: could not get system key
297 * -4: could not get SCI data
298 * -5: no user key found in SCI data
299 * -6: invalid user key
300 *****************************************************************************/
301 int drms_init( void *_p_drms, uint32_t i_type,
302 uint8_t *p_info, uint32_t i_len )
304 struct drms_s *p_drms = (struct drms_s *)_p_drms;
310 if( i_len < sizeof(p_drms->i_user) )
316 p_drms->i_user = U32_AT( p_info );
320 if( i_len < sizeof(p_drms->i_key) )
326 p_drms->i_key = U32_AT( p_info );
330 if( i_len < sizeof(p_drms->p_key) )
336 memcpy( p_drms->p_iviv, p_info, 16 );
340 p_drms->p_name = (uint8_t*) strdup( (char *)p_info );
342 if( p_drms->p_name == NULL )
350 uint32_t p_priv[ 64 ];
360 AddMD5( &md5, p_drms->p_name, strlen( (char *)p_drms->p_name ) );
361 AddMD5( &md5, p_drms->p_iviv, 16 );
364 if( p_drms->i_user == 0 && p_drms->i_key == 0 )
366 static const char p_secret[] = "tr1-th3n.y00_by3";
367 memcpy( p_drms->p_key, p_secret, 16 );
368 REVERSE( p_drms->p_key, 4 );
372 i_ret = GetUserKey( p_drms, p_drms->p_key );
379 InitAES( &p_drms->aes, p_drms->p_key );
381 memcpy( p_priv, p_info, 64 );
382 memcpy( p_drms->p_key, md5.p_digest, 16 );
383 drms_decrypt( p_drms, p_priv, 64, NULL );
384 REVERSE( p_priv, 64 );
386 if( p_priv[ 0 ] != 0x6e757469 ) /* itun */
392 InitAES( &p_drms->aes, p_priv + 6 );
393 memcpy( p_drms->p_key, p_priv + 12, 16 );
395 free( (void *)p_drms->p_name );
396 p_drms->p_name = NULL;
404 /* The following functions are local */
406 /*****************************************************************************
407 * InitAES: initialise AES/Rijndael encryption/decryption tables
408 *****************************************************************************
409 * The Advanced Encryption Standard (AES) is described in RFC 3268
410 *****************************************************************************/
411 static void InitAES( struct aes_s *p_aes, uint32_t *p_key )
414 uint32_t i_key, i_seed;
416 memset( p_aes->pp_enc_keys[1], 0, 16 );
417 memcpy( p_aes->pp_enc_keys[0], p_key, 16 );
419 /* Generate the key tables */
420 i_seed = p_aes->pp_enc_keys[ 0 ][ 3 ];
422 for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
426 i_seed = AES_ROR( i_seed, 8 );
428 j = p_aes_table[ i_key ];
430 j ^= p_aes_encrypt[ (i_seed >> 24) & 0xff ]
431 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 16) & 0xff ], 8 )
432 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 8) & 0xff ], 16 )
433 ^ AES_ROR( p_aes_encrypt[ i_seed & 0xff ], 24 );
435 j ^= p_aes->pp_enc_keys[ i_key ][ 0 ];
436 p_aes->pp_enc_keys[ i_key + 1 ][ 0 ] = j;
437 j ^= p_aes->pp_enc_keys[ i_key ][ 1 ];
438 p_aes->pp_enc_keys[ i_key + 1 ][ 1 ] = j;
439 j ^= p_aes->pp_enc_keys[ i_key ][ 2 ];
440 p_aes->pp_enc_keys[ i_key + 1 ][ 2 ] = j;
441 j ^= p_aes->pp_enc_keys[ i_key ][ 3 ];
442 p_aes->pp_enc_keys[ i_key + 1 ][ 3 ] = j;
447 memcpy( p_aes->pp_dec_keys[ 0 ],
448 p_aes->pp_enc_keys[ 0 ], 16 );
450 for( i = 1; i < AES_KEY_COUNT; i++ )
452 for( t = 0; t < 4; t++ )
454 uint32_t j, k, l, m, n;
456 j = p_aes->pp_enc_keys[ i ][ t ];
458 k = (((j >> 7) & 0x01010101) * 27) ^ ((j & 0xff7f7f7f) << 1);
459 l = (((k >> 7) & 0x01010101) * 27) ^ ((k & 0xff7f7f7f) << 1);
460 m = (((l >> 7) & 0x01010101) * 27) ^ ((l & 0xff7f7f7f) << 1);
464 n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
466 p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
471 /*****************************************************************************
472 * DecryptAES: decrypt an AES/Rijndael 128 bit block
473 *****************************************************************************/
474 static void DecryptAES( struct aes_s *p_aes,
475 uint32_t *p_dest, const uint32_t *p_src )
477 uint32_t p_wtxt[ 4 ]; /* Working cyphertext */
479 unsigned int i_round, t;
481 for( t = 0; t < 4; t++ )
483 /* FIXME: are there any endianness issues here? */
484 p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
488 for( i_round = 0; i_round < (AES_KEY_COUNT - 1); i_round++ )
490 for( t = 0; t < 4; t++ )
492 p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
495 for( t = 0; t < 4; t++ )
497 p_wtxt[ t ] = p_tmp[ t ]
498 ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - i_round ][ t ];
502 /* Final round (9) */
503 for( t = 0; t < 4; t++ )
505 p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
506 p_dest[ t ] ^= p_aes->pp_dec_keys[ 0 ][ t ];
511 /*****************************************************************************
512 * InitMD5: initialise an MD5 message
513 *****************************************************************************
514 * The MD5 message-digest algorithm is described in RFC 1321
515 *****************************************************************************/
516 static void InitMD5( struct md5_s *p_md5 )
518 p_md5->p_digest[ 0 ] = 0x67452301;
519 p_md5->p_digest[ 1 ] = 0xefcdab89;
520 p_md5->p_digest[ 2 ] = 0x98badcfe;
521 p_md5->p_digest[ 3 ] = 0x10325476;
523 memset( p_md5->p_data, 0, 64 );
527 /*****************************************************************************
528 * AddMD5: add i_len bytes to an MD5 message
529 *****************************************************************************/
530 static void AddMD5( struct md5_s *p_md5, const uint8_t *p_src, uint32_t i_len )
532 unsigned int i_current; /* Current bytes in the spare buffer */
533 unsigned int i_offset = 0;
535 i_current = (p_md5->i_bits / 8) & 63;
537 p_md5->i_bits += 8 * i_len;
539 /* If we can complete our spare buffer to 64 bytes, do it and add the
540 * resulting buffer to the MD5 message */
541 if( i_len >= (64 - i_current) )
543 memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src,
545 Digest( p_md5, p_md5->p_data );
547 i_offset += (64 - i_current);
548 i_len -= (64 - i_current);
552 /* Add as many entire 64 bytes blocks as we can to the MD5 message */
555 uint32_t p_tmp[ 16 ];
556 memcpy( p_tmp, p_src + i_offset, 64 );
557 Digest( p_md5, p_tmp );
562 /* Copy our remaining data to the message's spare buffer */
563 memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src + i_offset, i_len );
566 /*****************************************************************************
567 * EndMD5: finish an MD5 message
568 *****************************************************************************
569 * This function adds adequate padding to the end of the message, and appends
570 * the bit count so that we end at a block boundary.
571 *****************************************************************************/
572 static void EndMD5( struct md5_s *p_md5 )
574 unsigned int i_current;
576 i_current = (p_md5->i_bits / 8) & 63;
578 /* Append 0x80 to our buffer. No boundary check because the temporary
579 * buffer cannot be full, otherwise AddMD5 would have emptied it. */
580 ((uint8_t *)p_md5->p_data)[ i_current++ ] = 0x80;
582 /* If less than 8 bytes are available at the end of the block, complete
583 * this 64 bytes block with zeros and add it to the message. We'll add
584 * our length at the end of the next block. */
587 memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (64 - i_current) );
588 Digest( p_md5, p_md5->p_data );
592 /* Fill the unused space in our last block with zeroes and put the
593 * message length at the end. */
594 memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (56 - i_current) );
595 p_md5->p_data[ 14 ] = p_md5->i_bits & 0xffffffff;
596 p_md5->p_data[ 15 ] = (p_md5->i_bits >> 32);
597 REVERSE( &p_md5->p_data[ 14 ], 2 );
599 Digest( p_md5, p_md5->p_data );
602 #define F1( x, y, z ) ((z) ^ ((x) & ((y) ^ (z))))
603 #define F2( x, y, z ) F1((z), (x), (y))
604 #define F3( x, y, z ) ((x) ^ (y) ^ (z))
605 #define F4( x, y, z ) ((y) ^ ((x) | ~(z)))
607 #define MD5_DO( f, w, x, y, z, data, s ) \
608 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
610 /*****************************************************************************
611 * Digest: update the MD5 digest with 64 bytes of data
612 *****************************************************************************/
613 static void Digest( struct md5_s *p_md5, uint32_t *p_input )
617 REVERSE( p_input, 16 );
619 a = p_md5->p_digest[ 0 ];
620 b = p_md5->p_digest[ 1 ];
621 c = p_md5->p_digest[ 2 ];
622 d = p_md5->p_digest[ 3 ];
624 MD5_DO( F1, a, b, c, d, p_input[ 0 ] + 0xd76aa478, 7 );
625 MD5_DO( F1, d, a, b, c, p_input[ 1 ] + 0xe8c7b756, 12 );
626 MD5_DO( F1, c, d, a, b, p_input[ 2 ] + 0x242070db, 17 );
627 MD5_DO( F1, b, c, d, a, p_input[ 3 ] + 0xc1bdceee, 22 );
628 MD5_DO( F1, a, b, c, d, p_input[ 4 ] + 0xf57c0faf, 7 );
629 MD5_DO( F1, d, a, b, c, p_input[ 5 ] + 0x4787c62a, 12 );
630 MD5_DO( F1, c, d, a, b, p_input[ 6 ] + 0xa8304613, 17 );
631 MD5_DO( F1, b, c, d, a, p_input[ 7 ] + 0xfd469501, 22 );
632 MD5_DO( F1, a, b, c, d, p_input[ 8 ] + 0x698098d8, 7 );
633 MD5_DO( F1, d, a, b, c, p_input[ 9 ] + 0x8b44f7af, 12 );
634 MD5_DO( F1, c, d, a, b, p_input[ 10 ] + 0xffff5bb1, 17 );
635 MD5_DO( F1, b, c, d, a, p_input[ 11 ] + 0x895cd7be, 22 );
636 MD5_DO( F1, a, b, c, d, p_input[ 12 ] + 0x6b901122, 7 );
637 MD5_DO( F1, d, a, b, c, p_input[ 13 ] + 0xfd987193, 12 );
638 MD5_DO( F1, c, d, a, b, p_input[ 14 ] + 0xa679438e, 17 );
639 MD5_DO( F1, b, c, d, a, p_input[ 15 ] + 0x49b40821, 22 );
641 MD5_DO( F2, a, b, c, d, p_input[ 1 ] + 0xf61e2562, 5 );
642 MD5_DO( F2, d, a, b, c, p_input[ 6 ] + 0xc040b340, 9 );
643 MD5_DO( F2, c, d, a, b, p_input[ 11 ] + 0x265e5a51, 14 );
644 MD5_DO( F2, b, c, d, a, p_input[ 0 ] + 0xe9b6c7aa, 20 );
645 MD5_DO( F2, a, b, c, d, p_input[ 5 ] + 0xd62f105d, 5 );
646 MD5_DO( F2, d, a, b, c, p_input[ 10 ] + 0x02441453, 9 );
647 MD5_DO( F2, c, d, a, b, p_input[ 15 ] + 0xd8a1e681, 14 );
648 MD5_DO( F2, b, c, d, a, p_input[ 4 ] + 0xe7d3fbc8, 20 );
649 MD5_DO( F2, a, b, c, d, p_input[ 9 ] + 0x21e1cde6, 5 );
650 MD5_DO( F2, d, a, b, c, p_input[ 14 ] + 0xc33707d6, 9 );
651 MD5_DO( F2, c, d, a, b, p_input[ 3 ] + 0xf4d50d87, 14 );
652 MD5_DO( F2, b, c, d, a, p_input[ 8 ] + 0x455a14ed, 20 );
653 MD5_DO( F2, a, b, c, d, p_input[ 13 ] + 0xa9e3e905, 5 );
654 MD5_DO( F2, d, a, b, c, p_input[ 2 ] + 0xfcefa3f8, 9 );
655 MD5_DO( F2, c, d, a, b, p_input[ 7 ] + 0x676f02d9, 14 );
656 MD5_DO( F2, b, c, d, a, p_input[ 12 ] + 0x8d2a4c8a, 20 );
658 MD5_DO( F3, a, b, c, d, p_input[ 5 ] + 0xfffa3942, 4 );
659 MD5_DO( F3, d, a, b, c, p_input[ 8 ] + 0x8771f681, 11 );
660 MD5_DO( F3, c, d, a, b, p_input[ 11 ] + 0x6d9d6122, 16 );
661 MD5_DO( F3, b, c, d, a, p_input[ 14 ] + 0xfde5380c, 23 );
662 MD5_DO( F3, a, b, c, d, p_input[ 1 ] + 0xa4beea44, 4 );
663 MD5_DO( F3, d, a, b, c, p_input[ 4 ] + 0x4bdecfa9, 11 );
664 MD5_DO( F3, c, d, a, b, p_input[ 7 ] + 0xf6bb4b60, 16 );
665 MD5_DO( F3, b, c, d, a, p_input[ 10 ] + 0xbebfbc70, 23 );
666 MD5_DO( F3, a, b, c, d, p_input[ 13 ] + 0x289b7ec6, 4 );
667 MD5_DO( F3, d, a, b, c, p_input[ 0 ] + 0xeaa127fa, 11 );
668 MD5_DO( F3, c, d, a, b, p_input[ 3 ] + 0xd4ef3085, 16 );
669 MD5_DO( F3, b, c, d, a, p_input[ 6 ] + 0x04881d05, 23 );
670 MD5_DO( F3, a, b, c, d, p_input[ 9 ] + 0xd9d4d039, 4 );
671 MD5_DO( F3, d, a, b, c, p_input[ 12 ] + 0xe6db99e5, 11 );
672 MD5_DO( F3, c, d, a, b, p_input[ 15 ] + 0x1fa27cf8, 16 );
673 MD5_DO( F3, b, c, d, a, p_input[ 2 ] + 0xc4ac5665, 23 );
675 MD5_DO( F4, a, b, c, d, p_input[ 0 ] + 0xf4292244, 6 );
676 MD5_DO( F4, d, a, b, c, p_input[ 7 ] + 0x432aff97, 10 );
677 MD5_DO( F4, c, d, a, b, p_input[ 14 ] + 0xab9423a7, 15 );
678 MD5_DO( F4, b, c, d, a, p_input[ 5 ] + 0xfc93a039, 21 );
679 MD5_DO( F4, a, b, c, d, p_input[ 12 ] + 0x655b59c3, 6 );
680 MD5_DO( F4, d, a, b, c, p_input[ 3 ] + 0x8f0ccc92, 10 );
681 MD5_DO( F4, c, d, a, b, p_input[ 10 ] + 0xffeff47d, 15 );
682 MD5_DO( F4, b, c, d, a, p_input[ 1 ] + 0x85845dd1, 21 );
683 MD5_DO( F4, a, b, c, d, p_input[ 8 ] + 0x6fa87e4f, 6 );
684 MD5_DO( F4, d, a, b, c, p_input[ 15 ] + 0xfe2ce6e0, 10 );
685 MD5_DO( F4, c, d, a, b, p_input[ 6 ] + 0xa3014314, 15 );
686 MD5_DO( F4, b, c, d, a, p_input[ 13 ] + 0x4e0811a1, 21 );
687 MD5_DO( F4, a, b, c, d, p_input[ 4 ] + 0xf7537e82, 6 );
688 MD5_DO( F4, d, a, b, c, p_input[ 11 ] + 0xbd3af235, 10 );
689 MD5_DO( F4, c, d, a, b, p_input[ 2 ] + 0x2ad7d2bb, 15 );
690 MD5_DO( F4, b, c, d, a, p_input[ 9 ] + 0xeb86d391, 21 );
692 p_md5->p_digest[ 0 ] += a;
693 p_md5->p_digest[ 1 ] += b;
694 p_md5->p_digest[ 2 ] += c;
695 p_md5->p_digest[ 3 ] += d;
699 /*****************************************************************************
700 * InitShuffle: initialise a shuffle structure
701 *****************************************************************************
702 * This function initialises tables in the p_shuffle structure that will be
703 * used later by DoShuffle. The only external parameter is p_sys_key.
704 *****************************************************************************/
705 static void InitShuffle( struct shuffle_s *p_shuffle, uint32_t *p_sys_key,
708 char p_secret1[] = "Tv!*";
709 static const char p_secret2[] = "____v8rhvsaAvOKM____FfUH%798=[;."
710 "____f8677680a634____ba87fnOIf)(*";
713 p_shuffle->i_version = i_version;
715 /* Fill p_commands using the key and a secret seed */
716 for( i = 0; i < 20; i++ )
722 AddMD5( &md5, (const uint8_t *)p_sys_key, 16 );
723 AddMD5( &md5, (const uint8_t *)p_secret1, 4 );
728 REVERSE( md5.p_digest, 1 );
729 i_hash = ((int32_t)U32_AT(md5.p_digest)) % 1024;
731 p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
734 /* Fill p_bordel with completely meaningless initial values. */
735 memcpy( p_shuffle->p_bordel, p_secret2, 64 );
736 for( i = 0; i < 4; i++ )
738 p_shuffle->p_bordel[ 4 * i ] = U32_AT(p_sys_key + i);
739 REVERSE( p_shuffle->p_bordel + 4 * i + 1, 3 );
743 /*****************************************************************************
744 * DoShuffle: shuffle buffer
745 *****************************************************************************
746 * This is so ugly and uses so many MD5 checksums that it is most certainly
747 * one-way, though why it needs to be so complicated is beyond me.
748 *****************************************************************************/
749 static void DoShuffle( struct shuffle_s *p_shuffle,
750 uint32_t *p_buffer, uint32_t i_size )
753 uint32_t p_big_bordel[ 16 ];
754 uint32_t *p_bordel = p_shuffle->p_bordel;
757 static const uint32_t p_secret3[] =
759 0xAAAAAAAA, 0x01757700, 0x00554580, 0x01724500, 0x00424580,
760 0x01427700, 0x00000080, 0xC1D59D01, 0x80144981, 0x815C8901,
761 0x80544981, 0x81D45D01, 0x00000080, 0x81A3BB03, 0x00A2AA82,
762 0x01A3BB03, 0x0022A282, 0x813BA202, 0x00000080, 0x6D575737,
763 0x4A5275A5, 0x6D525725, 0x4A5254A5, 0x6B725437, 0x00000080,
764 0xD5DDB938, 0x5455A092, 0x5D95A013, 0x4415A192, 0xC5DD393A,
765 0x00000080, 0x55555555
767 static const uint32_t i_secret3 = sizeof(p_secret3)/sizeof(p_secret3[0]);
769 static const char p_secret4[] =
770 "pbclevtug (p) Nccyr Pbzchgre, Vap. Nyy Evtugf Erfreirq.";
771 static const uint32_t i_secret4 = sizeof(p_secret4)/sizeof(p_secret4[0]); /* It include the terminal '\0' */
773 /* Using the MD5 hash of a memory block is probably not one-way enough
774 * for the iTunes people. This function randomises p_bordel depending on
775 * the values in p_commands to make things even more messy in p_bordel. */
776 for( i = 0; i < 20; i++ )
778 uint8_t i_command, i_index;
780 if( !p_shuffle->p_commands[ i ] )
785 i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
786 i_index = p_shuffle->p_commands[ i ] & 0xff;
791 p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
792 + p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
795 p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
798 p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
801 p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
806 if( p_shuffle->i_version == 0x01000300 )
808 DoExtShuffle( p_bordel );
811 /* Convert our newly randomised p_bordel to big endianness and take
814 for( i = 0; i < 16; i++ )
816 p_big_bordel[ i ] = U32_AT(p_bordel + i);
818 AddMD5( &md5, (const uint8_t *)p_big_bordel, 64 );
819 if( p_shuffle->i_version == 0x01000300 )
821 uint32_t p_tmp3[i_secret3];
822 char p_tmp4[i_secret4];
824 memcpy( p_tmp3, p_secret3, sizeof(p_secret3) );
825 REVERSE( p_tmp3, i_secret3 );
827 #define ROT13(c) (((c)>='A'&&(c)<='Z')?(((c)-'A'+13)%26)+'A':\
828 ((c)>='a'&&(c)<='z')?(((c)-'a'+13)%26)+'a':c)
829 for( uint32_t i = 0; i < i_secret4; i++ )
830 p_tmp4[i] = ROT13( p_secret4[i] );
833 AddMD5( &md5, (const uint8_t *)p_tmp3, sizeof(p_secret3) );
834 AddMD5( &md5, (const uint8_t *)p_tmp4, i_secret4 );
838 /* XOR our buffer with the computed checksum */
839 for( i = 0; i < i_size; i++ )
841 p_buffer[ i ] ^= md5.p_digest[ i ];
845 /*****************************************************************************
846 * DoExtShuffle: extended shuffle
847 *****************************************************************************
848 * This is even uglier.
849 *****************************************************************************/
850 static void DoExtShuffle( uint32_t * p_bordel )
854 i_ret = FirstPass( p_bordel );
856 SecondPass( p_bordel, i_ret );
858 ThirdPass( p_bordel );
860 FourthPass( p_bordel );
863 static uint32_t FirstPass( uint32_t * p_bordel )
865 uint32_t i, i_cmd, i_ret = 5;
867 TinyShuffle1( p_bordel );
873 p_bordel[ 1 ] += 0x10000000;
874 p_bordel[ 3 ] += 0x12777;
876 if( (p_bordel[ 10 ] & 1) && i_ret )
879 p_bordel[ 1 ] -= p_bordel[ 2 ];
880 p_bordel[ 11 ] += p_bordel[ 12 ];
884 if( (p_bordel[ 1 ] + p_bordel[ 2 ]) >= 0x7D0 )
886 switch( ((p_bordel[ 3 ] ^ 0x567F) >> 2) & 7 )
889 for( i = 0; i < 3; i++ )
891 if( p_bordel[ i + 10 ] > 0x4E20 )
893 p_bordel[ i + 1 ] += p_bordel[ i + 2 ];
898 p_bordel[ 1 ] -= p_bordel[ 2 ];
901 p_bordel[ 11 ] += p_bordel[ 12 ];
904 p_bordel[ 3 ] ^= p_bordel[ 4 ];
907 p_bordel[ 13 ] &= p_bordel[ 14 ];
910 p_bordel[ 0 ] |= p_bordel[ 1 ];
922 for( i = 0, i_cmd = 0; i < 16; i++ )
924 if( p_bordel[ i ] < p_bordel[ i_cmd ] )
930 if( i_ret && i_cmd != 5 )
938 p_bordel[ 8 ] &= p_bordel[ 6 ] >> 1;
942 for( i = 0; i < 3; i++ )
945 if( p_bordel[ 11 ] & 5 )
947 p_bordel[ 8 ] += p_bordel[ 9 ];
957 i_cmd = (p_bordel[ 15 ] + 0x93) >> 3;
958 if( p_bordel[ 15 ] & 0x100 )
967 while( p_bordel[ 11 ] & 1 )
969 p_bordel[ 11 ] >>= 1;
974 p_bordel[ 14 ] -= 0x19FE;
986 i_cmd = ((p_bordel[ 3 ] + p_bordel[ 4 ] + 10) >> 1) - p_bordel[ 4 ];
994 p_bordel[ 14 ] >>= 1;
1000 p_bordel[ 12 ] |= 5;
1003 p_bordel[ 15 ] &= 0x55;
1006 p_bordel[ 2 ] &= 0xB62FC;
1012 TinyShuffle2( p_bordel );
1017 static void SecondPass( uint32_t * p_bordel, uint32_t i_tmp )
1019 uint32_t i, i_cmd, i_jc = 5;
1021 TinyShuffle3( p_bordel );
1023 for( i = 0, i_cmd = 0; i < 16; i++ )
1025 if( p_bordel[ i ] > p_bordel[ i_cmd ] )
1034 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
1040 if( (p_bordel[ 9 ] & 0x7777) == 0x3333 )
1047 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
1056 p_bordel[ 1 ] -= p_bordel[ 5 ];
1057 for( i = 0; i < 3; i++ )
1059 switch( p_bordel[ 1 ] & 3 )
1068 p_bordel[ 13 ] &= 0xFEFEFEF7;
1071 p_bordel[ 8 ] |= 0x80080011;
1083 p_bordel[ 15 ] ^= 0x18547EFF;
1089 switch( ( p_bordel[ 12 ] + p_bordel[ 13 ] + p_bordel[ 6 ] ) % 5 )
1092 p_bordel[ 12 ] -= 1;
1095 p_bordel[ 12 ] -= 1;
1096 p_bordel[ 13 ] += 1;
1099 p_bordel[ 13 ] += 4;
1102 p_bordel[ 12 ] -= 1;
1109 i = 3; /* Restart the whole loop */
1114 TinyShuffle4( p_bordel );
1118 TinyShuffle5( p_bordel );
1120 switch( ( p_bordel[ 2 ] * 2 + 15 ) % 5 )
1123 if( ( p_bordel[ 3 ] + i_tmp ) <=
1124 ( p_bordel[ 1 ] + p_bordel[ 15 ] ) )
1130 p_bordel[ 10 ] -= 0x13;
1133 p_bordel[ 5 ] >>= 2;
1137 if( !( p_bordel[ 2 ] & 1 ) || i_jc == 0 )
1143 p_bordel[ 2 ] += 0x13;
1144 p_bordel[ 12 ] += 1;
1147 p_bordel[ 2 ] &= 0x10076000;
1150 static void ThirdPass( uint32_t * p_bordel )
1154 i_cmd = ((p_bordel[ 7 ] + p_bordel[ 14 ] + 10) >> 1) - p_bordel[ 14 ];
1160 p_bordel[ 1 ] <<= 1;
1161 p_bordel[ 2 ] <<= 2;
1162 p_bordel[ 3 ] <<= 3;
1165 p_bordel[ i_cmd + 3 ] &= 0x5EDE36B;
1166 p_bordel[ 5 ] += p_bordel[ 8 ];
1167 p_bordel[ 4 ] += p_bordel[ 7 ];
1168 p_bordel[ 3 ] += p_bordel[ 6 ];
1169 p_bordel[ 2 ] += p_bordel[ 5 ];
1172 p_bordel[ 1 ] += p_bordel[ 4 ];
1173 p_bordel[ 0 ] += p_bordel[ 3 ];
1174 TinyShuffle6( p_bordel );
1175 return; /* jc = 4 */
1177 if( (p_bordel[ 11 ] & p_bordel[ 2 ]) > 0x211B )
1186 p_bordel[ 9 ] ^= p_bordel[ 2 ];
1189 p_bordel[ 2 ] ^= (p_bordel[ 1 ] & p_bordel[ 13 ]);
1192 p_bordel[ 0 ] -= p_bordel[ 11 ] & p_bordel[ 15 ];
1193 return; /* jc = 4 */
1195 p_bordel[ 6 ] >>= (p_bordel[ 14 ] & 3);
1199 SWAP( p_bordel[ 0 ], p_bordel[ 10 ] );
1201 TinyShuffle6( p_bordel );
1203 return; /* jc = 5 */
1206 static void FourthPass( uint32_t * p_bordel )
1210 TinyShuffle7( p_bordel );
1212 switch( p_bordel[ 5 ] % 5)
1218 p_bordel[ 11 ] ^= (p_bordel[ 3 ] + p_bordel[ 6 ] + p_bordel[ 8 ]);
1221 for( i = 4; i < 15 && (p_bordel[ i ] & 5) == 0; i++ )
1223 SWAP( p_bordel[ i ], p_bordel[ 15 - i ] );
1227 p_bordel[ 12 ] -= 1;
1228 p_bordel[ 13 ] += 1;
1229 p_bordel[ 2 ] -= 0x64;
1230 p_bordel[ 3 ] += 0x64;
1231 TinyShuffle8( p_bordel );
1235 for( i = 0, j = 0; i < 16; i++ )
1237 if( p_bordel[ i ] > p_bordel[ j ] )
1243 switch( p_bordel[ j ] % 100 )
1246 SWAP( p_bordel[ 0 ], p_bordel[ j ] );
1249 p_bordel[ 1 ] >>= 1;
1250 p_bordel[ 2 ] <<= 1;
1251 p_bordel[ 14 ] >>= 3;
1252 p_bordel[ 15 ] <<= 4;
1255 p_bordel[ j ] += p_bordel[ 13 ];
1258 p_bordel[ 1 ] += 0x20E;
1259 p_bordel[ 5 ] += 0x223D;
1260 p_bordel[ 13 ] -= 0x576;
1261 p_bordel[ 15 ] += 0x576;
1264 p_bordel[ 2 ] -= 0x64;
1265 p_bordel[ 3 ] += 0x64;
1266 p_bordel[ 12 ] -= 1;
1267 p_bordel[ 13 ] += 1;
1271 p_bordel[ j ] += p_bordel[ 13 ];
1275 TinyShuffle8( p_bordel );
1278 /*****************************************************************************
1279 * TinyShuffle[12345678]: tiny shuffle subroutines
1280 *****************************************************************************
1281 * These standalone functions are little helpers for the shuffling process.
1282 *****************************************************************************/
1283 static void TinyShuffle1( uint32_t * p_bordel )
1285 uint32_t i_cmd = (p_bordel[ 5 ] + 10) >> 2;
1287 if( p_bordel[ 5 ] > 0x7D0 )
1301 if( p_bordel[ 4 ] & 5 )
1303 p_bordel[ 1 ] ^= 0x4D;
1307 p_bordel[ 12 ] += 5;
1312 static void TinyShuffle2( uint32_t * p_bordel )
1316 for( i = 0, j = 0; i < 16; i++ )
1318 if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) )
1326 for( ; j < 15; j++ )
1328 p_bordel[ j ] += p_bordel[ j + 1 ];
1333 p_bordel[ 2 ] &= 0xB62FC;
1337 static void TinyShuffle3( uint32_t * p_bordel )
1339 uint32_t i_cmd = p_bordel[ 6 ] + 0x194B;
1341 if( p_bordel[ 6 ] > 0x2710 )
1349 p_bordel[ 3 ] += 0x19FE;
1352 p_bordel[ 7 ] -= p_bordel[ 3 ] >> 2;
1355 p_bordel[ 5 ] ^= 0x248A;
1360 static void TinyShuffle4( uint32_t * p_bordel )
1364 for( i = 0, j = 0; i < 16; i++ )
1366 if( p_bordel[ i ] < p_bordel[ j ] )
1372 if( (p_bordel[ j ] % (j + 1)) > 10 )
1375 p_bordel[ 2 ] += 0x13;
1376 p_bordel[ 12 ] += 1;
1380 static void TinyShuffle5( uint32_t * p_bordel )
1384 p_bordel[ 2 ] &= 0x7F3F;
1386 for( i = 0; i < 5; i++ )
1388 switch( ( p_bordel[ 2 ] + 10 + i ) % 5 )
1391 p_bordel[ 12 ] &= p_bordel[ 2 ];
1394 p_bordel[ 3 ] ^= p_bordel[ 15 ];
1397 p_bordel[ 15 ] += 0x576;
1400 p_bordel[ 7 ] -= 0x2D;
1403 p_bordel[ 1 ] <<= 1;
1409 static void TinyShuffle6( uint32_t * p_bordel )
1413 for( i = 0; i < 8; i++ )
1415 j = p_bordel[ 3 ] & 0x7514 ? 5 : 7;
1416 SWAP( p_bordel[ i ], p_bordel[ i + j ] );
1420 static void TinyShuffle7( uint32_t * p_bordel )
1424 i = (((p_bordel[ 9 ] + p_bordel[ 15 ] + 12) >> 2) - p_bordel[ 4 ]) & 7;
1428 SWAP( p_bordel[ i ], p_bordel[ i + 3 ] );
1431 SWAP( p_bordel[ 1 ], p_bordel[ 10 ] );
1434 static void TinyShuffle8( uint32_t * p_bordel )
1438 i = (p_bordel[ 0 ] & p_bordel[ 6 ]) & 0xF;
1440 switch( p_bordel[ i ] % 1000 )
1443 if( (p_bordel[ i ] & 0x777) > (p_bordel[ 7 ] & 0x5555) )
1445 p_bordel[ i ] ^= p_bordel[ 5 ] & p_bordel[ 3 ];
1449 p_bordel[ 15 ] &= 0x5555;
1452 p_bordel[ i ] ^= p_bordel[ 15 ];
1455 SWAP( p_bordel[ 0 ], p_bordel[ 3 ] );
1456 SWAP( p_bordel[ 1 ], p_bordel[ 6 ] );
1457 SWAP( p_bordel[ 3 ], p_bordel[ 6 ] );
1458 SWAP( p_bordel[ 4 ], p_bordel[ 9 ] );
1459 SWAP( p_bordel[ 5 ], p_bordel[ 8 ] );
1460 SWAP( p_bordel[ 6 ], p_bordel[ 7 ] );
1461 SWAP( p_bordel[ 13 ], p_bordel[ 14 ] );
1464 p_bordel[ i ] += p_bordel[ 1 ] ^ 0x80080011;
1465 p_bordel[ i ] += p_bordel[ 2 ] ^ 0xBEEFDEAD;
1466 p_bordel[ i ] += p_bordel[ 3 ] ^ 0x8765F444;
1467 p_bordel[ i ] += p_bordel[ 4 ] ^ 0x78145326;
1470 p_bordel[ 12 ] -= p_bordel[ i ];
1471 p_bordel[ 13 ] += p_bordel[ i ];
1474 p_bordel[ i ] += p_bordel[ 1 ];
1475 p_bordel[ i ] -= p_bordel[ 7 ];
1476 p_bordel[ i ] -= p_bordel[ 8 ];
1477 p_bordel[ i ] += p_bordel[ 9 ];
1478 p_bordel[ i ] += p_bordel[ 13 ];
1482 p_bordel[ i + 1 ] >>= 1;
1483 p_bordel[ i + 2 ] <<= 4;
1484 p_bordel[ i + 3 ] >>= 3;
1487 p_bordel[ 1 ] += 0x20E;
1488 p_bordel[ 5 ] += 0x223D;
1489 p_bordel[ 13 ] -= 0x576;
1490 p_bordel[ 15 ] += 0x576;
1493 if( (p_bordel[ i ] ^ 0x8765F441) < 0x2710 )
1495 SWAP( p_bordel[ 0 ], p_bordel[ 1 ] );
1499 SWAP( p_bordel[ 1 ], p_bordel[ 11 ] );
1505 /*****************************************************************************
1506 * GetSystemKey: get the system key
1507 *****************************************************************************
1508 * Compute the system key from various system information, see HashSystemInfo.
1509 *****************************************************************************/
1510 static int GetSystemKey( uint32_t *p_sys_key, bool b_ipod )
1512 static const char p_secret5[ 8 ] = "YuaFlafu";
1513 static const char p_secret6[ 8 ] = "zPif98ga";
1516 uint32_t p_system_hash[ 4 ];
1518 /* Compute the MD5 hash of our system info */
1519 if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) ||
1520 ( b_ipod && GetiPodID( &i_ipod_id ) ) )
1525 /* Combine our system info hash with additional secret data. The resulting
1526 * MD5 hash will be our system key. */
1528 AddMD5( &md5, (const uint8_t*)p_secret5, 8 );
1532 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1533 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1534 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1535 AddMD5( &md5, (const uint8_t *)p_secret6, 8 );
1539 i_ipod_id = U64_AT(&i_ipod_id);
1540 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1541 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1542 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1547 memcpy( p_sys_key, md5.p_digest, 16 );
1553 # define DRMS_DIRNAME "drms"
1555 # define DRMS_DIRNAME ".drms"
1558 /*****************************************************************************
1559 * WriteUserKey: write the user key to hard disk
1560 *****************************************************************************
1561 * Write the user key to the hard disk so that it can be reused later or used
1562 * on operating systems other than Win32.
1563 *****************************************************************************/
1564 static int WriteUserKey( void *_p_drms, uint32_t *p_user_key )
1566 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1569 char psz_path[ PATH_MAX ];
1571 snprintf( psz_path, PATH_MAX - 1,
1572 "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
1574 #if defined( WIN32 )
1575 if( !mkdir( psz_path ) || errno == EEXIST )
1577 if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
1580 snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d",
1581 p_drms->psz_homedir, p_drms->i_user, p_drms->i_key );
1583 file = utf8_fopen( psz_path, "wb" );
1586 i_ret = fwrite( p_user_key, sizeof(uint32_t),
1587 4, file ) == 4 ? 0 : -1;
1595 /*****************************************************************************
1596 * ReadUserKey: read the user key from hard disk
1597 *****************************************************************************
1598 * Retrieve the user key from the hard disk if available.
1599 *****************************************************************************/
1600 static int ReadUserKey( void *_p_drms, uint32_t *p_user_key )
1602 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1605 char psz_path[ PATH_MAX ];
1607 snprintf( psz_path, PATH_MAX - 1,
1608 "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir,
1609 p_drms->i_user, p_drms->i_key );
1611 file = utf8_fopen( psz_path, "rb" );
1614 i_ret = fread( p_user_key, sizeof(uint32_t),
1615 4, file ) == 4 ? 0 : -1;
1622 /*****************************************************************************
1623 * GetUserKey: get the user key
1624 *****************************************************************************
1625 * Retrieve the user key from the hard disk if available, otherwise generate
1626 * it from the system key. If the key could be successfully generated, write
1627 * it to the hard disk for future use.
1628 *****************************************************************************/
1629 static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
1631 static const char p_secret7[] = "mUfnpognadfgf873";
1632 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1634 struct shuffle_s shuffle;
1636 uint32_t *p_sci_data = NULL;
1637 uint32_t i_user, i_key;
1638 uint32_t p_sys_key[ 4 ];
1639 uint32_t i_sci_size = 0, i_blocks, i_remaining;
1640 uint32_t *p_sci0, *p_sci1, *p_buffer;
1641 uint32_t p_sci_key[ 4 ];
1645 if( ReadUserKey( p_drms, p_user_key ) == 0 )
1647 REVERSE( p_user_key, 4 );
1651 psz_ipod = getenv( "IPOD" );
1653 if( GetSystemKey( p_sys_key, psz_ipod ? true : false ) )
1658 if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
1663 /* Phase 1: unscramble the SCI data using the system key and shuffle
1664 * it using DoShuffle(). */
1666 /* Skip the first 4 bytes (some sort of header). Decrypt the rest. */
1667 i_blocks = (i_sci_size - 4) / 16;
1668 i_remaining = (i_sci_size - 4) - (i_blocks * 16);
1669 p_buffer = p_sci_data + 1;
1671 /* Decrypt and shuffle our data at the same time */
1672 InitAES( &aes, p_sys_key );
1673 REVERSE( p_sys_key, 4 );
1674 REVERSE( p_sci_data, 1 );
1675 InitShuffle( &shuffle, p_sys_key, p_sci_data[ 0 ] );
1677 memcpy( p_sci_key, p_secret7, 16 );
1678 REVERSE( p_sci_key, 4 );
1682 uint32_t p_tmp[ 4 ];
1684 REVERSE( p_buffer, 4 );
1685 DecryptAES( &aes, p_tmp, p_buffer );
1686 BlockXOR( p_tmp, p_sci_key, p_tmp );
1688 /* Use the previous scrambled data as the key for next block */
1689 memcpy( p_sci_key, p_buffer, 16 );
1691 /* Shuffle the decrypted data using a custom routine */
1692 DoShuffle( &shuffle, p_tmp, 4 );
1694 /* Copy this block back to p_buffer */
1695 memcpy( p_buffer, p_tmp, 16 );
1700 if( i_remaining >= 4 )
1702 REVERSE( p_buffer, i_remaining / 4 );
1703 DoShuffle( &shuffle, p_buffer, i_remaining / 4 );
1706 /* Phase 2: look for the user key in the generated data. I must admit I
1707 * do not understand what is going on here, because it almost
1708 * looks like we are browsing data that makes sense, even though
1709 * the DoShuffle() part made it completely meaningless. */
1712 REVERSE( p_sci_data + 5, 1 );
1713 i = U32_AT( p_sci_data + 5 );
1714 i_sci_size -= 22 * sizeof(uint32_t);
1715 p_sci1 = p_sci_data + 22;
1718 while( i_sci_size >= 20 && i > 0 )
1720 if( p_sci0 == NULL )
1722 i_sci_size -= 18 * sizeof(uint32_t);
1723 if( i_sci_size < 20 )
1729 REVERSE( p_sci1 + 17, 1 );
1730 y = U32_AT( p_sci1 + 17 );
1741 i_user = U32_AT( p_sci0 );
1742 i_key = U32_AT( p_sci1 );
1743 REVERSE( &i_user, 1 );
1744 REVERSE( &i_key, 1 );
1745 if( i_user == p_drms->i_user && ( ( i_key == p_drms->i_key ) ||
1746 ( !p_drms->i_key && ( p_sci1 == (p_sci0 + 18) ) ) ) )
1748 memcpy( p_user_key, p_sci1 + 1, 16 );
1749 REVERSE( p_sci1 + 1, 4 );
1750 WriteUserKey( p_drms, p_sci1 + 1 );
1757 i_sci_size -= 5 * sizeof(uint32_t);
1765 /*****************************************************************************
1766 * GetSCIData: get SCI data from "SC Info.sidb"
1767 *****************************************************************************
1768 * Read SCI data from "\Apple Computer\iTunes\SC Info\SC Info.sidb"
1769 *****************************************************************************/
1770 static int GetSCIData( char *psz_ipod, uint32_t **pp_sci,
1771 uint32_t *pi_sci_size )
1774 char *psz_path = NULL;
1775 char p_tmp[ 4 * PATH_MAX ];
1778 if( psz_ipod == NULL )
1781 const wchar_t *wfile =
1782 L"\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb";
1783 typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
1785 HINSTANCE shfolder_dll = NULL;
1786 SHGETFOLDERPATH dSHGetFolderPath = NULL;
1787 wchar_t wpath[PATH_MAX];
1789 if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
1792 (SHGETFOLDERPATH)GetProcAddress( shfolder_dll,
1793 _T("SHGetFolderPathW") );
1796 if( dSHGetFolderPath != NULL &&
1797 SUCCEEDED( dSHGetFolderPath( NULL, CSIDL_COMMON_APPDATA,
1798 NULL, 0, wpath ) ) )
1800 if (wcslen( wpath ) + wcslen( wfile ) >= PATH_MAX )
1804 wcscat( wpath, wfile );
1806 psz_path = FromWide( wpath );
1807 strncpy( p_tmp, psz_path, sizeof( p_tmp ) - 1 );
1808 p_tmp[sizeof( p_tmp ) - 1] = '\0';
1813 if( shfolder_dll != NULL )
1815 FreeLibrary( shfolder_dll );
1821 #define ISCINFO "iSCInfo"
1822 if( strstr( psz_ipod, ISCINFO ) == NULL )
1824 snprintf( p_tmp, sizeof(p_tmp) - 1,
1825 "%s/iPod_Control/iTunes/" ISCINFO "2", psz_ipod );
1830 psz_path = psz_ipod;
1834 if( psz_path == NULL )
1839 file = utf8_fopen( psz_path, "rb" );
1844 if( !fstat( fileno( file ), &st ) && st.st_size >= 4 )
1846 *pp_sci = malloc( st.st_size );
1847 if( *pp_sci != NULL )
1849 if( fread( *pp_sci, 1, st.st_size,
1850 file ) == (size_t)st.st_size )
1852 *pi_sci_size = st.st_size;
1857 free( (void *)*pp_sci );
1869 /*****************************************************************************
1870 * HashSystemInfo: hash system information
1871 *****************************************************************************
1872 * This function computes the MD5 hash of the C: hard drive serial number,
1873 * BIOS version, CPU type and Windows version.
1874 *****************************************************************************/
1875 static int HashSystemInfo( uint32_t *p_system_hash )
1887 static const LPCTSTR p_reg_keys[ 3 ][ 2 ] =
1890 _T("HARDWARE\\DESCRIPTION\\System"),
1891 _T("SystemBiosVersion")
1895 _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
1896 _T("ProcessorNameString")
1900 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
1907 AddMD5( &md5, "cache-control", 13 );
1908 AddMD5( &md5, "Ethernet", 8 );
1910 GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
1911 NULL, NULL, NULL, 0 );
1912 AddMD5( &md5, (const uint8_t *)&i_serial, 4 );
1914 for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
1916 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
1917 0, KEY_READ, &i_key ) != ERROR_SUCCESS )
1922 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1923 NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
1925 RegCloseKey( i_key );
1929 p_reg_buf = malloc( i_size );
1931 if( p_reg_buf != NULL )
1933 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1934 NULL, NULL, p_reg_buf,
1935 &i_size ) == ERROR_SUCCESS )
1937 AddMD5( &md5, (const uint8_t *)p_reg_buf, i_size );
1943 RegCloseKey( i_key );
1952 memcpy( p_system_hash, md5.p_digest, 16 );
1957 /*****************************************************************************
1958 * GetiPodID: Get iPod ID
1959 *****************************************************************************
1960 * This function gets the iPod ID.
1961 *****************************************************************************/
1962 static int GetiPodID( int64_t *p_ipod_id )
1966 #define PROD_NAME "iPod"
1967 #define VENDOR_NAME "Apple Computer, Inc."
1969 char *psz_ipod_id = getenv( "IPODID" );
1970 if( psz_ipod_id != NULL )
1972 *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
1980 io_iterator_t iterator;
1981 CFMutableDictionaryRef match_dic;
1982 CFMutableDictionaryRef smatch_dic;
1984 if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
1986 smatch_dic = IOServiceMatching( "IOFireWireUnit" );
1987 match_dic = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
1988 &kCFTypeDictionaryKeyCallBacks,
1989 &kCFTypeDictionaryValueCallBacks );
1991 if( smatch_dic != NULL && match_dic != NULL )
1993 CFDictionarySetValue( smatch_dic,
1994 CFSTR("FireWire Vendor Name"),
1995 CFSTR(VENDOR_NAME) );
1996 CFDictionarySetValue( smatch_dic,
1997 CFSTR("FireWire Product Name"),
2000 CFDictionarySetValue( match_dic,
2001 CFSTR(kIOPropertyMatchKey),
2004 if( IOServiceGetMatchingServices( port, match_dic,
2005 &iterator ) == KERN_SUCCESS )
2007 while( ( device = IOIteratorNext( iterator ) ) != NULL )
2009 value = IORegistryEntryCreateCFProperty( device,
2010 CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );
2014 if( CFGetTypeID( value ) == CFNumberGetTypeID() )
2017 CFNumberGetValue( (CFNumberRef)value,
2018 kCFNumberLongLongType,
2020 *p_ipod_id = i_ipod_id;
2027 IOObjectRelease( device );
2032 IOObjectRelease( iterator );
2034 CFRelease( match_dic );
2037 mach_port_deallocate( mach_task_self(), port );
2040 #elif defined (HAVE_SYSFS_LIBSYSFS_H)
2041 struct sysfs_bus *bus = NULL;
2042 struct dlist *devlist = NULL;
2043 struct dlist *attributes = NULL;
2044 struct sysfs_device *curdev = NULL;
2045 struct sysfs_attribute *curattr = NULL;
2047 bus = sysfs_open_bus( "ieee1394" );
2050 devlist = sysfs_get_bus_devices( bus );
2051 if( devlist != NULL )
2053 dlist_for_each_data( devlist, curdev, struct sysfs_device )
2055 attributes = sysfs_get_device_attributes( curdev );
2056 if( attributes != NULL )
2058 dlist_for_each_data( attributes, curattr,
2059 struct sysfs_attribute )
2061 if( ( strcmp( curattr->name, "model_name" ) == 0 ) &&
2062 ( strncmp( curattr->value, PROD_NAME,
2063 sizeof(PROD_NAME) ) == 0 ) )
2065 *p_ipod_id = strtoll( curdev->name, NULL, 16 );
2076 sysfs_close_bus( bus );
2083 #else /* !defined( UNDER_CE ) */
2085 void *drms_alloc( const char *psz_homedir ){ return NULL; }
2086 void drms_free( void *a ){}
2087 void drms_decrypt( void *a, uint32_t *b, uint32_t c, uint32_t *k ){}
2088 void drms_get_p_key( void *p_drms, uint32_t *p_key ){}
2089 int drms_init( void *a, uint32_t b, uint8_t *c, uint32_t d ){ return -1; }
2091 #endif /* defined( UNDER_CE ) */