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>
49 # if !defined( UNDER_CE )
57 #ifdef HAVE_SYS_STAT_H
58 # include <sys/stat.h>
60 #ifdef HAVE_SYS_TYPES_H
61 # include <sys/types.h>
64 /* In Solaris (and perhaps others) PATH_MAX is in limits.h. */
68 # include <mach/mach.h>
69 # include <IOKit/IOKitLib.h>
70 # include <CoreFoundation/CFNumber.h>
73 #ifdef HAVE_SYSFS_LIBSYSFS_H
74 # include <sysfs/libsysfs.h>
78 #include "drmstables.h"
80 #if !defined( UNDER_CE )
81 /*****************************************************************************
82 * aes_s: AES keys structure
83 *****************************************************************************
84 * This structure stores a set of keys usable for encryption and decryption
85 * with the AES/Rijndael algorithm.
86 *****************************************************************************/
89 uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
90 uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
94 # define Digest DigestMD5
96 /*****************************************************************************
97 * md5_s: MD5 message structure
98 *****************************************************************************
99 * This structure stores the static information needed to compute an MD5
100 * hash. It has an extra data buffer to allow non-aligned writes.
101 *****************************************************************************/
104 uint64_t i_bits; /* Total written bits */
105 uint32_t p_digest[4]; /* The MD5 digest */
106 uint32_t p_data[16]; /* Buffer to cache non-aligned writes */
110 /*****************************************************************************
111 * shuffle_s: shuffle structure
112 *****************************************************************************
113 * This structure stores the static information needed to shuffle data using
114 * a custom algorithm.
115 *****************************************************************************/
119 uint32_t p_commands[ 20 ];
120 uint32_t p_bordel[ 16 ];
123 #define SWAP( a, b ) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
125 /*****************************************************************************
126 * drms_s: DRMS structure
127 *****************************************************************************
128 * This structure stores the static information needed to decrypt DRMS data.
129 *****************************************************************************/
134 uint8_t p_iviv[ 16 ];
140 char psz_homedir[ PATH_MAX ];
143 /*****************************************************************************
145 *****************************************************************************/
146 static void InitAES ( struct aes_s *, uint32_t * );
147 static void DecryptAES ( struct aes_s *, uint32_t *, const uint32_t * );
150 static void InitMD5 ( struct md5_s * );
151 static void AddMD5 ( struct md5_s *, const uint8_t *, uint32_t );
152 static void EndMD5 ( struct md5_s * );
153 static void Digest ( struct md5_s *, uint32_t * );
156 static void InitShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
157 static void DoShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
159 static uint32_t FirstPass ( uint32_t * );
160 static void SecondPass ( uint32_t *, uint32_t );
161 static void ThirdPass ( uint32_t * );
162 static void FourthPass ( uint32_t * );
163 static void TinyShuffle1 ( uint32_t * );
164 static void TinyShuffle2 ( uint32_t * );
165 static void TinyShuffle3 ( uint32_t * );
166 static void TinyShuffle4 ( uint32_t * );
167 static void TinyShuffle5 ( uint32_t * );
168 static void TinyShuffle6 ( uint32_t * );
169 static void TinyShuffle7 ( uint32_t * );
170 static void TinyShuffle8 ( uint32_t * );
171 static void DoExtShuffle ( uint32_t * );
173 static int GetSystemKey ( uint32_t *, bool );
174 static int WriteUserKey ( void *, uint32_t * );
175 static int ReadUserKey ( void *, uint32_t * );
176 static int GetUserKey ( void *, uint32_t * );
178 static int GetSCIData ( char *, uint32_t **, uint32_t * );
179 static int HashSystemInfo ( uint32_t * );
180 static int GetiPodID ( int64_t * );
182 #ifdef WORDS_BIGENDIAN
183 /*****************************************************************************
184 * Reverse: reverse byte order
185 *****************************************************************************/
186 static inline void Reverse( uint32_t *p_buffer, int n )
190 for( i = 0; i < n; i++ )
192 p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
195 # define REVERSE( p, n ) Reverse( p, n )
197 # define REVERSE( p, n )
200 /*****************************************************************************
201 * BlockXOR: XOR two 128 bit blocks
202 *****************************************************************************/
203 static inline void BlockXOR( uint32_t *p_dest, uint32_t *p_s1, uint32_t *p_s2 )
207 for( i = 0; i < 4; i++ )
209 p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
213 /*****************************************************************************
214 * drms_alloc: allocate a DRMS structure
215 *****************************************************************************/
216 void *drms_alloc( const char *psz_homedir )
218 struct drms_s *p_drms;
220 p_drms = malloc( sizeof(struct drms_s) );
227 memset( p_drms, 0, sizeof(struct drms_s) );
229 strncpy( p_drms->psz_homedir, psz_homedir, PATH_MAX );
230 p_drms->psz_homedir[ PATH_MAX - 1 ] = '\0';
232 return (void *)p_drms;
235 /*****************************************************************************
236 * drms_free: free a previously allocated DRMS structure
237 *****************************************************************************/
238 void drms_free( void *_p_drms )
240 struct drms_s *p_drms = (struct drms_s *)_p_drms;
242 if( p_drms->p_name != NULL )
244 free( (void *)p_drms->p_name );
250 /*****************************************************************************
251 * drms_decrypt: unscramble a chunk of data
252 *****************************************************************************/
253 void drms_decrypt( void *_p_drms, uint32_t *p_buffer, uint32_t i_bytes, uint32_t *p_key )
255 struct drms_s *p_drms = (struct drms_s *)_p_drms;
256 uint32_t p_key_buf[ 4 ];
257 unsigned int i_blocks;
259 /* AES is a block cypher, round down the byte count */
260 i_blocks = i_bytes / 16;
261 i_bytes = i_blocks * 16;
263 /* Initialise the key */
267 memcpy( p_key, p_drms->p_key, 16 );
275 REVERSE( p_buffer, 4 );
276 DecryptAES( &p_drms->aes, p_tmp, p_buffer );
277 BlockXOR( p_tmp, p_key, p_tmp );
279 /* Use the previous scrambled data as the key for next block */
280 memcpy( p_key, p_buffer, 16 );
282 /* Copy unscrambled data back to the buffer */
283 memcpy( p_buffer, p_tmp, 16 );
284 REVERSE( p_buffer, 4 );
290 /*****************************************************************************
291 * drms_get_p_key: copy the p_key into user buffer
292 ****************************************************************************/
293 void drms_get_p_key( void *_p_drms, uint32_t *p_key )
295 struct drms_s *p_drms = (struct drms_s *)_p_drms;
297 memcpy( p_key, p_drms->p_key, 16 );
300 /*****************************************************************************
301 * drms_init: initialise a DRMS structure
302 *****************************************************************************
306 * -2: invalid argument
307 * -3: could not get system key
308 * -4: could not get SCI data
309 * -5: no user key found in SCI data
310 * -6: invalid user key
311 *****************************************************************************/
312 int drms_init( void *_p_drms, uint32_t i_type,
313 uint8_t *p_info, uint32_t i_len )
315 struct drms_s *p_drms = (struct drms_s *)_p_drms;
321 if( i_len < sizeof(p_drms->i_user) )
327 p_drms->i_user = U32_AT( p_info );
331 if( i_len < sizeof(p_drms->i_key) )
337 p_drms->i_key = U32_AT( p_info );
341 if( i_len < sizeof(p_drms->p_key) )
347 memcpy( p_drms->p_iviv, p_info, 16 );
351 p_drms->p_name = (uint8_t*) strdup( (char *)p_info );
353 if( p_drms->p_name == NULL )
361 uint32_t p_priv[ 64 ];
371 AddMD5( &md5, p_drms->p_name, strlen( (char *)p_drms->p_name ) );
372 AddMD5( &md5, p_drms->p_iviv, 16 );
375 if( p_drms->i_user == 0 && p_drms->i_key == 0 )
377 static const char p_secret[] = "tr1-th3n.y00_by3";
378 memcpy( p_drms->p_key, p_secret, 16 );
379 REVERSE( p_drms->p_key, 4 );
383 i_ret = GetUserKey( p_drms, p_drms->p_key );
390 InitAES( &p_drms->aes, p_drms->p_key );
392 memcpy( p_priv, p_info, 64 );
393 memcpy( p_drms->p_key, md5.p_digest, 16 );
394 drms_decrypt( p_drms, p_priv, 64, NULL );
395 REVERSE( p_priv, 64 );
397 if( p_priv[ 0 ] != 0x6e757469 ) /* itun */
403 InitAES( &p_drms->aes, p_priv + 6 );
404 memcpy( p_drms->p_key, p_priv + 12, 16 );
406 free( (void *)p_drms->p_name );
407 p_drms->p_name = NULL;
415 /* The following functions are local */
417 /*****************************************************************************
418 * InitAES: initialise AES/Rijndael encryption/decryption tables
419 *****************************************************************************
420 * The Advanced Encryption Standard (AES) is described in RFC 3268
421 *****************************************************************************/
422 static void InitAES( struct aes_s *p_aes, uint32_t *p_key )
425 uint32_t i_key, i_seed;
427 memset( p_aes->pp_enc_keys[1], 0, 16 );
428 memcpy( p_aes->pp_enc_keys[0], p_key, 16 );
430 /* Generate the key tables */
431 i_seed = p_aes->pp_enc_keys[ 0 ][ 3 ];
433 for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
437 i_seed = AES_ROR( i_seed, 8 );
439 j = p_aes_table[ i_key ];
441 j ^= p_aes_encrypt[ (i_seed >> 24) & 0xff ]
442 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 16) & 0xff ], 8 )
443 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 8) & 0xff ], 16 )
444 ^ AES_ROR( p_aes_encrypt[ i_seed & 0xff ], 24 );
446 j ^= p_aes->pp_enc_keys[ i_key ][ 0 ];
447 p_aes->pp_enc_keys[ i_key + 1 ][ 0 ] = j;
448 j ^= p_aes->pp_enc_keys[ i_key ][ 1 ];
449 p_aes->pp_enc_keys[ i_key + 1 ][ 1 ] = j;
450 j ^= p_aes->pp_enc_keys[ i_key ][ 2 ];
451 p_aes->pp_enc_keys[ i_key + 1 ][ 2 ] = j;
452 j ^= p_aes->pp_enc_keys[ i_key ][ 3 ];
453 p_aes->pp_enc_keys[ i_key + 1 ][ 3 ] = j;
458 memcpy( p_aes->pp_dec_keys[ 0 ],
459 p_aes->pp_enc_keys[ 0 ], 16 );
461 for( i = 1; i < AES_KEY_COUNT; i++ )
463 for( t = 0; t < 4; t++ )
465 uint32_t j, k, l, m, n;
467 j = p_aes->pp_enc_keys[ i ][ t ];
469 k = (((j >> 7) & 0x01010101) * 27) ^ ((j & 0xff7f7f7f) << 1);
470 l = (((k >> 7) & 0x01010101) * 27) ^ ((k & 0xff7f7f7f) << 1);
471 m = (((l >> 7) & 0x01010101) * 27) ^ ((l & 0xff7f7f7f) << 1);
475 n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
477 p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
482 /*****************************************************************************
483 * DecryptAES: decrypt an AES/Rijndael 128 bit block
484 *****************************************************************************/
485 static void DecryptAES( struct aes_s *p_aes,
486 uint32_t *p_dest, const uint32_t *p_src )
488 uint32_t p_wtxt[ 4 ]; /* Working cyphertext */
490 unsigned int i_round, t;
492 for( t = 0; t < 4; t++ )
494 /* FIXME: are there any endianness issues here? */
495 p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
499 for( i_round = 0; i_round < (AES_KEY_COUNT - 1); i_round++ )
501 for( t = 0; t < 4; t++ )
503 p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
506 for( t = 0; t < 4; t++ )
508 p_wtxt[ t ] = p_tmp[ t ]
509 ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - i_round ][ t ];
513 /* Final round (9) */
514 for( t = 0; t < 4; t++ )
516 p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
517 p_dest[ t ] ^= p_aes->pp_dec_keys[ 0 ][ t ];
522 /*****************************************************************************
523 * InitMD5: initialise an MD5 message
524 *****************************************************************************
525 * The MD5 message-digest algorithm is described in RFC 1321
526 *****************************************************************************/
527 static void InitMD5( struct md5_s *p_md5 )
529 p_md5->p_digest[ 0 ] = 0x67452301;
530 p_md5->p_digest[ 1 ] = 0xefcdab89;
531 p_md5->p_digest[ 2 ] = 0x98badcfe;
532 p_md5->p_digest[ 3 ] = 0x10325476;
534 memset( p_md5->p_data, 0, 64 );
538 /*****************************************************************************
539 * AddMD5: add i_len bytes to an MD5 message
540 *****************************************************************************/
541 static void AddMD5( struct md5_s *p_md5, const uint8_t *p_src, uint32_t i_len )
543 unsigned int i_current; /* Current bytes in the spare buffer */
544 unsigned int i_offset = 0;
546 i_current = (p_md5->i_bits / 8) & 63;
548 p_md5->i_bits += 8 * i_len;
550 /* If we can complete our spare buffer to 64 bytes, do it and add the
551 * resulting buffer to the MD5 message */
552 if( i_len >= (64 - i_current) )
554 memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src,
556 Digest( p_md5, p_md5->p_data );
558 i_offset += (64 - i_current);
559 i_len -= (64 - i_current);
563 /* Add as many entire 64 bytes blocks as we can to the MD5 message */
566 uint32_t p_tmp[ 16 ];
567 memcpy( p_tmp, p_src + i_offset, 64 );
568 Digest( p_md5, p_tmp );
573 /* Copy our remaining data to the message's spare buffer */
574 memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src + i_offset, i_len );
577 /*****************************************************************************
578 * EndMD5: finish an MD5 message
579 *****************************************************************************
580 * This function adds adequate padding to the end of the message, and appends
581 * the bit count so that we end at a block boundary.
582 *****************************************************************************/
583 static void EndMD5( struct md5_s *p_md5 )
585 unsigned int i_current;
587 i_current = (p_md5->i_bits / 8) & 63;
589 /* Append 0x80 to our buffer. No boundary check because the temporary
590 * buffer cannot be full, otherwise AddMD5 would have emptied it. */
591 ((uint8_t *)p_md5->p_data)[ i_current++ ] = 0x80;
593 /* If less than 8 bytes are available at the end of the block, complete
594 * this 64 bytes block with zeros and add it to the message. We'll add
595 * our length at the end of the next block. */
598 memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (64 - i_current) );
599 Digest( p_md5, p_md5->p_data );
603 /* Fill the unused space in our last block with zeroes and put the
604 * message length at the end. */
605 memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (56 - i_current) );
606 p_md5->p_data[ 14 ] = p_md5->i_bits & 0xffffffff;
607 p_md5->p_data[ 15 ] = (p_md5->i_bits >> 32);
608 REVERSE( &p_md5->p_data[ 14 ], 2 );
610 Digest( p_md5, p_md5->p_data );
613 #define F1( x, y, z ) ((z) ^ ((x) & ((y) ^ (z))))
614 #define F2( x, y, z ) F1((z), (x), (y))
615 #define F3( x, y, z ) ((x) ^ (y) ^ (z))
616 #define F4( x, y, z ) ((y) ^ ((x) | ~(z)))
618 #define MD5_DO( f, w, x, y, z, data, s ) \
619 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
621 /*****************************************************************************
622 * Digest: update the MD5 digest with 64 bytes of data
623 *****************************************************************************/
624 static void Digest( struct md5_s *p_md5, uint32_t *p_input )
628 REVERSE( p_input, 16 );
630 a = p_md5->p_digest[ 0 ];
631 b = p_md5->p_digest[ 1 ];
632 c = p_md5->p_digest[ 2 ];
633 d = p_md5->p_digest[ 3 ];
635 MD5_DO( F1, a, b, c, d, p_input[ 0 ] + 0xd76aa478, 7 );
636 MD5_DO( F1, d, a, b, c, p_input[ 1 ] + 0xe8c7b756, 12 );
637 MD5_DO( F1, c, d, a, b, p_input[ 2 ] + 0x242070db, 17 );
638 MD5_DO( F1, b, c, d, a, p_input[ 3 ] + 0xc1bdceee, 22 );
639 MD5_DO( F1, a, b, c, d, p_input[ 4 ] + 0xf57c0faf, 7 );
640 MD5_DO( F1, d, a, b, c, p_input[ 5 ] + 0x4787c62a, 12 );
641 MD5_DO( F1, c, d, a, b, p_input[ 6 ] + 0xa8304613, 17 );
642 MD5_DO( F1, b, c, d, a, p_input[ 7 ] + 0xfd469501, 22 );
643 MD5_DO( F1, a, b, c, d, p_input[ 8 ] + 0x698098d8, 7 );
644 MD5_DO( F1, d, a, b, c, p_input[ 9 ] + 0x8b44f7af, 12 );
645 MD5_DO( F1, c, d, a, b, p_input[ 10 ] + 0xffff5bb1, 17 );
646 MD5_DO( F1, b, c, d, a, p_input[ 11 ] + 0x895cd7be, 22 );
647 MD5_DO( F1, a, b, c, d, p_input[ 12 ] + 0x6b901122, 7 );
648 MD5_DO( F1, d, a, b, c, p_input[ 13 ] + 0xfd987193, 12 );
649 MD5_DO( F1, c, d, a, b, p_input[ 14 ] + 0xa679438e, 17 );
650 MD5_DO( F1, b, c, d, a, p_input[ 15 ] + 0x49b40821, 22 );
652 MD5_DO( F2, a, b, c, d, p_input[ 1 ] + 0xf61e2562, 5 );
653 MD5_DO( F2, d, a, b, c, p_input[ 6 ] + 0xc040b340, 9 );
654 MD5_DO( F2, c, d, a, b, p_input[ 11 ] + 0x265e5a51, 14 );
655 MD5_DO( F2, b, c, d, a, p_input[ 0 ] + 0xe9b6c7aa, 20 );
656 MD5_DO( F2, a, b, c, d, p_input[ 5 ] + 0xd62f105d, 5 );
657 MD5_DO( F2, d, a, b, c, p_input[ 10 ] + 0x02441453, 9 );
658 MD5_DO( F2, c, d, a, b, p_input[ 15 ] + 0xd8a1e681, 14 );
659 MD5_DO( F2, b, c, d, a, p_input[ 4 ] + 0xe7d3fbc8, 20 );
660 MD5_DO( F2, a, b, c, d, p_input[ 9 ] + 0x21e1cde6, 5 );
661 MD5_DO( F2, d, a, b, c, p_input[ 14 ] + 0xc33707d6, 9 );
662 MD5_DO( F2, c, d, a, b, p_input[ 3 ] + 0xf4d50d87, 14 );
663 MD5_DO( F2, b, c, d, a, p_input[ 8 ] + 0x455a14ed, 20 );
664 MD5_DO( F2, a, b, c, d, p_input[ 13 ] + 0xa9e3e905, 5 );
665 MD5_DO( F2, d, a, b, c, p_input[ 2 ] + 0xfcefa3f8, 9 );
666 MD5_DO( F2, c, d, a, b, p_input[ 7 ] + 0x676f02d9, 14 );
667 MD5_DO( F2, b, c, d, a, p_input[ 12 ] + 0x8d2a4c8a, 20 );
669 MD5_DO( F3, a, b, c, d, p_input[ 5 ] + 0xfffa3942, 4 );
670 MD5_DO( F3, d, a, b, c, p_input[ 8 ] + 0x8771f681, 11 );
671 MD5_DO( F3, c, d, a, b, p_input[ 11 ] + 0x6d9d6122, 16 );
672 MD5_DO( F3, b, c, d, a, p_input[ 14 ] + 0xfde5380c, 23 );
673 MD5_DO( F3, a, b, c, d, p_input[ 1 ] + 0xa4beea44, 4 );
674 MD5_DO( F3, d, a, b, c, p_input[ 4 ] + 0x4bdecfa9, 11 );
675 MD5_DO( F3, c, d, a, b, p_input[ 7 ] + 0xf6bb4b60, 16 );
676 MD5_DO( F3, b, c, d, a, p_input[ 10 ] + 0xbebfbc70, 23 );
677 MD5_DO( F3, a, b, c, d, p_input[ 13 ] + 0x289b7ec6, 4 );
678 MD5_DO( F3, d, a, b, c, p_input[ 0 ] + 0xeaa127fa, 11 );
679 MD5_DO( F3, c, d, a, b, p_input[ 3 ] + 0xd4ef3085, 16 );
680 MD5_DO( F3, b, c, d, a, p_input[ 6 ] + 0x04881d05, 23 );
681 MD5_DO( F3, a, b, c, d, p_input[ 9 ] + 0xd9d4d039, 4 );
682 MD5_DO( F3, d, a, b, c, p_input[ 12 ] + 0xe6db99e5, 11 );
683 MD5_DO( F3, c, d, a, b, p_input[ 15 ] + 0x1fa27cf8, 16 );
684 MD5_DO( F3, b, c, d, a, p_input[ 2 ] + 0xc4ac5665, 23 );
686 MD5_DO( F4, a, b, c, d, p_input[ 0 ] + 0xf4292244, 6 );
687 MD5_DO( F4, d, a, b, c, p_input[ 7 ] + 0x432aff97, 10 );
688 MD5_DO( F4, c, d, a, b, p_input[ 14 ] + 0xab9423a7, 15 );
689 MD5_DO( F4, b, c, d, a, p_input[ 5 ] + 0xfc93a039, 21 );
690 MD5_DO( F4, a, b, c, d, p_input[ 12 ] + 0x655b59c3, 6 );
691 MD5_DO( F4, d, a, b, c, p_input[ 3 ] + 0x8f0ccc92, 10 );
692 MD5_DO( F4, c, d, a, b, p_input[ 10 ] + 0xffeff47d, 15 );
693 MD5_DO( F4, b, c, d, a, p_input[ 1 ] + 0x85845dd1, 21 );
694 MD5_DO( F4, a, b, c, d, p_input[ 8 ] + 0x6fa87e4f, 6 );
695 MD5_DO( F4, d, a, b, c, p_input[ 15 ] + 0xfe2ce6e0, 10 );
696 MD5_DO( F4, c, d, a, b, p_input[ 6 ] + 0xa3014314, 15 );
697 MD5_DO( F4, b, c, d, a, p_input[ 13 ] + 0x4e0811a1, 21 );
698 MD5_DO( F4, a, b, c, d, p_input[ 4 ] + 0xf7537e82, 6 );
699 MD5_DO( F4, d, a, b, c, p_input[ 11 ] + 0xbd3af235, 10 );
700 MD5_DO( F4, c, d, a, b, p_input[ 2 ] + 0x2ad7d2bb, 15 );
701 MD5_DO( F4, b, c, d, a, p_input[ 9 ] + 0xeb86d391, 21 );
703 p_md5->p_digest[ 0 ] += a;
704 p_md5->p_digest[ 1 ] += b;
705 p_md5->p_digest[ 2 ] += c;
706 p_md5->p_digest[ 3 ] += d;
710 /*****************************************************************************
711 * InitShuffle: initialise a shuffle structure
712 *****************************************************************************
713 * This function initialises tables in the p_shuffle structure that will be
714 * used later by DoShuffle. The only external parameter is p_sys_key.
715 *****************************************************************************/
716 static void InitShuffle( struct shuffle_s *p_shuffle, uint32_t *p_sys_key,
719 char p_secret1[] = "Tv!*";
720 static const char p_secret2[] = "____v8rhvsaAvOKM____FfUH%798=[;."
721 "____f8677680a634____ba87fnOIf)(*";
724 p_shuffle->i_version = i_version;
726 /* Fill p_commands using the key and a secret seed */
727 for( i = 0; i < 20; i++ )
733 AddMD5( &md5, (const uint8_t *)p_sys_key, 16 );
734 AddMD5( &md5, (const uint8_t *)p_secret1, 4 );
739 REVERSE( md5.p_digest, 1 );
740 i_hash = ((int32_t)U32_AT(md5.p_digest)) % 1024;
742 p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
745 /* Fill p_bordel with completely meaningless initial values. */
746 memcpy( p_shuffle->p_bordel, p_secret2, 64 );
747 for( i = 0; i < 4; i++ )
749 p_shuffle->p_bordel[ 4 * i ] = U32_AT(p_sys_key + i);
750 REVERSE( p_shuffle->p_bordel + 4 * i + 1, 3 );
754 /*****************************************************************************
755 * DoShuffle: shuffle buffer
756 *****************************************************************************
757 * This is so ugly and uses so many MD5 checksums that it is most certainly
758 * one-way, though why it needs to be so complicated is beyond me.
759 *****************************************************************************/
760 static void DoShuffle( struct shuffle_s *p_shuffle,
761 uint32_t *p_buffer, uint32_t i_size )
764 uint32_t p_big_bordel[ 16 ];
765 uint32_t *p_bordel = p_shuffle->p_bordel;
768 static const uint32_t p_secret3[] =
770 0xAAAAAAAA, 0x01757700, 0x00554580, 0x01724500, 0x00424580,
771 0x01427700, 0x00000080, 0xC1D59D01, 0x80144981, 0x815C8901,
772 0x80544981, 0x81D45D01, 0x00000080, 0x81A3BB03, 0x00A2AA82,
773 0x01A3BB03, 0x0022A282, 0x813BA202, 0x00000080, 0x6D575737,
774 0x4A5275A5, 0x6D525725, 0x4A5254A5, 0x6B725437, 0x00000080,
775 0xD5DDB938, 0x5455A092, 0x5D95A013, 0x4415A192, 0xC5DD393A,
776 0x00000080, 0x55555555
778 static const uint32_t i_secret3 = sizeof(p_secret3)/sizeof(p_secret3[0]);
780 static const char p_secret4[] =
781 "pbclevtug (p) Nccyr Pbzchgre, Vap. Nyy Evtugf Erfreirq.";
782 static const uint32_t i_secret4 = sizeof(p_secret4)/sizeof(p_secret4[0]); /* It include the terminal '\0' */
784 /* Using the MD5 hash of a memory block is probably not one-way enough
785 * for the iTunes people. This function randomises p_bordel depending on
786 * the values in p_commands to make things even more messy in p_bordel. */
787 for( i = 0; i < 20; i++ )
789 uint8_t i_command, i_index;
791 if( !p_shuffle->p_commands[ i ] )
796 i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
797 i_index = p_shuffle->p_commands[ i ] & 0xff;
802 p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
803 + p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
806 p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
809 p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
812 p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
817 if( p_shuffle->i_version == 0x01000300 )
819 DoExtShuffle( p_bordel );
822 /* Convert our newly randomised p_bordel to big endianness and take
825 for( i = 0; i < 16; i++ )
827 p_big_bordel[ i ] = U32_AT(p_bordel + i);
829 AddMD5( &md5, (const uint8_t *)p_big_bordel, 64 );
830 if( p_shuffle->i_version == 0x01000300 )
832 uint32_t p_tmp3[i_secret3];
833 char p_tmp4[i_secret4];
835 memcpy( p_tmp3, p_secret3, sizeof(p_secret3) );
836 REVERSE( p_tmp3, i_secret3 );
838 #define ROT13(c) (((c)>='A'&&(c)<='Z')?(((c)-'A'+13)%26)+'A':\
839 ((c)>='a'&&(c)<='z')?(((c)-'a'+13)%26)+'a':c)
840 for( uint32_t i = 0; i < i_secret4; i++ )
841 p_tmp4[i] = ROT13( p_secret4[i] );
844 AddMD5( &md5, (const uint8_t *)p_tmp3, sizeof(p_secret3) );
845 AddMD5( &md5, (const uint8_t *)p_tmp4, i_secret4 );
849 /* XOR our buffer with the computed checksum */
850 for( i = 0; i < i_size; i++ )
852 p_buffer[ i ] ^= md5.p_digest[ i ];
856 /*****************************************************************************
857 * DoExtShuffle: extended shuffle
858 *****************************************************************************
859 * This is even uglier.
860 *****************************************************************************/
861 static void DoExtShuffle( uint32_t * p_bordel )
865 i_ret = FirstPass( p_bordel );
867 SecondPass( p_bordel, i_ret );
869 ThirdPass( p_bordel );
871 FourthPass( p_bordel );
874 static uint32_t FirstPass( uint32_t * p_bordel )
876 uint32_t i, i_cmd, i_ret = 5;
878 TinyShuffle1( p_bordel );
884 p_bordel[ 1 ] += 0x10000000;
885 p_bordel[ 3 ] += 0x12777;
887 if( (p_bordel[ 10 ] & 1) && i_ret )
890 p_bordel[ 1 ] -= p_bordel[ 2 ];
891 p_bordel[ 11 ] += p_bordel[ 12 ];
895 if( (p_bordel[ 1 ] + p_bordel[ 2 ]) >= 0x7D0 )
897 switch( ((p_bordel[ 3 ] ^ 0x567F) >> 2) & 7 )
900 for( i = 0; i < 3; i++ )
902 if( p_bordel[ i + 10 ] > 0x4E20 )
904 p_bordel[ i + 1 ] += p_bordel[ i + 2 ];
909 p_bordel[ 1 ] -= p_bordel[ 2 ];
912 p_bordel[ 11 ] += p_bordel[ 12 ];
915 p_bordel[ 3 ] ^= p_bordel[ 4 ];
918 p_bordel[ 13 ] &= p_bordel[ 14 ];
921 p_bordel[ 0 ] |= p_bordel[ 1 ];
933 for( i = 0, i_cmd = 0; i < 16; i++ )
935 if( p_bordel[ i ] < p_bordel[ i_cmd ] )
941 if( i_ret && i_cmd != 5 )
949 p_bordel[ 8 ] &= p_bordel[ 6 ] >> 1;
953 for( i = 0; i < 3; i++ )
956 if( p_bordel[ 11 ] & 5 )
958 p_bordel[ 8 ] += p_bordel[ 9 ];
968 i_cmd = (p_bordel[ 15 ] + 0x93) >> 3;
969 if( p_bordel[ 15 ] & 0x100 )
978 while( p_bordel[ 11 ] & 1 )
980 p_bordel[ 11 ] >>= 1;
985 p_bordel[ 14 ] -= 0x19FE;
997 i_cmd = ((p_bordel[ 3 ] + p_bordel[ 4 ] + 10) >> 1) - p_bordel[ 4 ];
1005 p_bordel[ 14 ] >>= 1;
1008 p_bordel[ 5 ] <<= 2;
1011 p_bordel[ 12 ] |= 5;
1014 p_bordel[ 15 ] &= 0x55;
1017 p_bordel[ 2 ] &= 0xB62FC;
1023 TinyShuffle2( p_bordel );
1028 static void SecondPass( uint32_t * p_bordel, uint32_t i_tmp )
1030 uint32_t i, i_cmd, i_jc = 5;
1032 TinyShuffle3( p_bordel );
1034 for( i = 0, i_cmd = 0; i < 16; i++ )
1036 if( p_bordel[ i ] > p_bordel[ i_cmd ] )
1045 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
1051 if( (p_bordel[ 9 ] & 0x7777) == 0x3333 )
1058 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
1067 p_bordel[ 1 ] -= p_bordel[ 5 ];
1068 for( i = 0; i < 3; i++ )
1070 switch( p_bordel[ 1 ] & 3 )
1079 p_bordel[ 13 ] &= 0xFEFEFEF7;
1082 p_bordel[ 8 ] |= 0x80080011;
1094 p_bordel[ 15 ] ^= 0x18547EFF;
1100 switch( ( p_bordel[ 12 ] + p_bordel[ 13 ] + p_bordel[ 6 ] ) % 5 )
1103 p_bordel[ 12 ] -= 1;
1106 p_bordel[ 12 ] -= 1;
1107 p_bordel[ 13 ] += 1;
1110 p_bordel[ 13 ] += 4;
1113 p_bordel[ 12 ] -= 1;
1120 i = 3; /* Restart the whole loop */
1125 TinyShuffle4( p_bordel );
1129 TinyShuffle5( p_bordel );
1131 switch( ( p_bordel[ 2 ] * 2 + 15 ) % 5 )
1134 if( ( p_bordel[ 3 ] + i_tmp ) <=
1135 ( p_bordel[ 1 ] + p_bordel[ 15 ] ) )
1141 p_bordel[ 10 ] -= 0x13;
1144 p_bordel[ 5 ] >>= 2;
1148 if( !( p_bordel[ 2 ] & 1 ) || i_jc == 0 )
1154 p_bordel[ 2 ] += 0x13;
1155 p_bordel[ 12 ] += 1;
1158 p_bordel[ 2 ] &= 0x10076000;
1161 static void ThirdPass( uint32_t * p_bordel )
1165 i_cmd = ((p_bordel[ 7 ] + p_bordel[ 14 ] + 10) >> 1) - p_bordel[ 14 ];
1171 p_bordel[ 1 ] <<= 1;
1172 p_bordel[ 2 ] <<= 2;
1173 p_bordel[ 3 ] <<= 3;
1176 p_bordel[ i_cmd + 3 ] &= 0x5EDE36B;
1177 p_bordel[ 5 ] += p_bordel[ 8 ];
1178 p_bordel[ 4 ] += p_bordel[ 7 ];
1179 p_bordel[ 3 ] += p_bordel[ 6 ];
1180 p_bordel[ 2 ] += p_bordel[ 5 ];
1183 p_bordel[ 1 ] += p_bordel[ 4 ];
1184 p_bordel[ 0 ] += p_bordel[ 3 ];
1185 TinyShuffle6( p_bordel );
1186 return; /* jc = 4 */
1188 if( (p_bordel[ 11 ] & p_bordel[ 2 ]) > 0x211B )
1197 p_bordel[ 9 ] ^= p_bordel[ 2 ];
1200 p_bordel[ 2 ] ^= (p_bordel[ 1 ] & p_bordel[ 13 ]);
1203 p_bordel[ 0 ] -= p_bordel[ 11 ] & p_bordel[ 15 ];
1204 return; /* jc = 4 */
1206 p_bordel[ 6 ] >>= (p_bordel[ 14 ] & 3);
1210 SWAP( p_bordel[ 0 ], p_bordel[ 10 ] );
1212 TinyShuffle6( p_bordel );
1214 return; /* jc = 5 */
1217 static void FourthPass( uint32_t * p_bordel )
1221 TinyShuffle7( p_bordel );
1223 switch( p_bordel[ 5 ] % 5)
1229 p_bordel[ 11 ] ^= (p_bordel[ 3 ] + p_bordel[ 6 ] + p_bordel[ 8 ]);
1232 for( i = 4; i < 15 && (p_bordel[ i ] & 5) == 0; i++ )
1234 SWAP( p_bordel[ i ], p_bordel[ 15 - i ] );
1238 p_bordel[ 12 ] -= 1;
1239 p_bordel[ 13 ] += 1;
1240 p_bordel[ 2 ] -= 0x64;
1241 p_bordel[ 3 ] += 0x64;
1242 TinyShuffle8( p_bordel );
1246 for( i = 0, j = 0; i < 16; i++ )
1248 if( p_bordel[ i ] > p_bordel[ j ] )
1254 switch( p_bordel[ j ] % 100 )
1257 SWAP( p_bordel[ 0 ], p_bordel[ j ] );
1260 p_bordel[ 1 ] >>= 1;
1261 p_bordel[ 2 ] <<= 1;
1262 p_bordel[ 14 ] >>= 3;
1263 p_bordel[ 15 ] <<= 4;
1266 p_bordel[ j ] += p_bordel[ 13 ];
1269 p_bordel[ 1 ] += 0x20E;
1270 p_bordel[ 5 ] += 0x223D;
1271 p_bordel[ 13 ] -= 0x576;
1272 p_bordel[ 15 ] += 0x576;
1275 p_bordel[ 2 ] -= 0x64;
1276 p_bordel[ 3 ] += 0x64;
1277 p_bordel[ 12 ] -= 1;
1278 p_bordel[ 13 ] += 1;
1282 p_bordel[ j ] += p_bordel[ 13 ];
1286 TinyShuffle8( p_bordel );
1289 /*****************************************************************************
1290 * TinyShuffle[12345678]: tiny shuffle subroutines
1291 *****************************************************************************
1292 * These standalone functions are little helpers for the shuffling process.
1293 *****************************************************************************/
1294 static void TinyShuffle1( uint32_t * p_bordel )
1296 uint32_t i_cmd = (p_bordel[ 5 ] + 10) >> 2;
1298 if( p_bordel[ 5 ] > 0x7D0 )
1312 if( p_bordel[ 4 ] & 5 )
1314 p_bordel[ 1 ] ^= 0x4D;
1318 p_bordel[ 12 ] += 5;
1323 static void TinyShuffle2( uint32_t * p_bordel )
1327 for( i = 0, j = 0; i < 16; i++ )
1329 if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) )
1337 for( ; j < 15; j++ )
1339 p_bordel[ j ] += p_bordel[ j + 1 ];
1344 p_bordel[ 2 ] &= 0xB62FC;
1348 static void TinyShuffle3( uint32_t * p_bordel )
1350 uint32_t i_cmd = p_bordel[ 6 ] + 0x194B;
1352 if( p_bordel[ 6 ] > 0x2710 )
1360 p_bordel[ 3 ] += 0x19FE;
1363 p_bordel[ 7 ] -= p_bordel[ 3 ] >> 2;
1366 p_bordel[ 5 ] ^= 0x248A;
1371 static void TinyShuffle4( uint32_t * p_bordel )
1375 for( i = 0, j = 0; i < 16; i++ )
1377 if( p_bordel[ i ] < p_bordel[ j ] )
1383 if( (p_bordel[ j ] % (j + 1)) > 10 )
1386 p_bordel[ 2 ] += 0x13;
1387 p_bordel[ 12 ] += 1;
1391 static void TinyShuffle5( uint32_t * p_bordel )
1395 p_bordel[ 2 ] &= 0x7F3F;
1397 for( i = 0; i < 5; i++ )
1399 switch( ( p_bordel[ 2 ] + 10 + i ) % 5 )
1402 p_bordel[ 12 ] &= p_bordel[ 2 ];
1405 p_bordel[ 3 ] ^= p_bordel[ 15 ];
1408 p_bordel[ 15 ] += 0x576;
1411 p_bordel[ 7 ] -= 0x2D;
1414 p_bordel[ 1 ] <<= 1;
1420 static void TinyShuffle6( uint32_t * p_bordel )
1424 for( i = 0; i < 8; i++ )
1426 j = p_bordel[ 3 ] & 0x7514 ? 5 : 7;
1427 SWAP( p_bordel[ i ], p_bordel[ i + j ] );
1431 static void TinyShuffle7( uint32_t * p_bordel )
1435 i = (((p_bordel[ 9 ] + p_bordel[ 15 ] + 12) >> 2) - p_bordel[ 4 ]) & 7;
1439 SWAP( p_bordel[ i ], p_bordel[ i + 3 ] );
1442 SWAP( p_bordel[ 1 ], p_bordel[ 10 ] );
1445 static void TinyShuffle8( uint32_t * p_bordel )
1449 i = (p_bordel[ 0 ] & p_bordel[ 6 ]) & 0xF;
1451 switch( p_bordel[ i ] % 1000 )
1454 if( (p_bordel[ i ] & 0x777) > (p_bordel[ 7 ] & 0x5555) )
1456 p_bordel[ i ] ^= p_bordel[ 5 ] & p_bordel[ 3 ];
1460 p_bordel[ 15 ] &= 0x5555;
1463 p_bordel[ i ] ^= p_bordel[ 15 ];
1466 SWAP( p_bordel[ 0 ], p_bordel[ 3 ] );
1467 SWAP( p_bordel[ 1 ], p_bordel[ 6 ] );
1468 SWAP( p_bordel[ 3 ], p_bordel[ 6 ] );
1469 SWAP( p_bordel[ 4 ], p_bordel[ 9 ] );
1470 SWAP( p_bordel[ 5 ], p_bordel[ 8 ] );
1471 SWAP( p_bordel[ 6 ], p_bordel[ 7 ] );
1472 SWAP( p_bordel[ 13 ], p_bordel[ 14 ] );
1475 p_bordel[ i ] += p_bordel[ 1 ] ^ 0x80080011;
1476 p_bordel[ i ] += p_bordel[ 2 ] ^ 0xBEEFDEAD;
1477 p_bordel[ i ] += p_bordel[ 3 ] ^ 0x8765F444;
1478 p_bordel[ i ] += p_bordel[ 4 ] ^ 0x78145326;
1481 p_bordel[ 12 ] -= p_bordel[ i ];
1482 p_bordel[ 13 ] += p_bordel[ i ];
1485 p_bordel[ i ] += p_bordel[ 1 ];
1486 p_bordel[ i ] -= p_bordel[ 7 ];
1487 p_bordel[ i ] -= p_bordel[ 8 ];
1488 p_bordel[ i ] += p_bordel[ 9 ];
1489 p_bordel[ i ] += p_bordel[ 13 ];
1493 p_bordel[ i + 1 ] >>= 1;
1494 p_bordel[ i + 2 ] <<= 4;
1495 p_bordel[ i + 3 ] >>= 3;
1498 p_bordel[ 1 ] += 0x20E;
1499 p_bordel[ 5 ] += 0x223D;
1500 p_bordel[ 13 ] -= 0x576;
1501 p_bordel[ 15 ] += 0x576;
1504 if( (p_bordel[ i ] ^ 0x8765F441) < 0x2710 )
1506 SWAP( p_bordel[ 0 ], p_bordel[ 1 ] );
1510 SWAP( p_bordel[ 1 ], p_bordel[ 11 ] );
1516 /*****************************************************************************
1517 * GetSystemKey: get the system key
1518 *****************************************************************************
1519 * Compute the system key from various system information, see HashSystemInfo.
1520 *****************************************************************************/
1521 static int GetSystemKey( uint32_t *p_sys_key, bool b_ipod )
1523 static const char p_secret5[ 8 ] = "YuaFlafu";
1524 static const char p_secret6[ 8 ] = "zPif98ga";
1527 uint32_t p_system_hash[ 4 ];
1529 /* Compute the MD5 hash of our system info */
1530 if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) ||
1531 ( b_ipod && GetiPodID( &i_ipod_id ) ) )
1536 /* Combine our system info hash with additional secret data. The resulting
1537 * MD5 hash will be our system key. */
1539 AddMD5( &md5, (const uint8_t*)p_secret5, 8 );
1543 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1544 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1545 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1546 AddMD5( &md5, (const uint8_t *)p_secret6, 8 );
1550 i_ipod_id = U64_AT(&i_ipod_id);
1551 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1552 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1553 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1558 memcpy( p_sys_key, md5.p_digest, 16 );
1564 # define DRMS_DIRNAME "drms"
1566 # define DRMS_DIRNAME ".drms"
1569 /*****************************************************************************
1570 * WriteUserKey: write the user key to hard disk
1571 *****************************************************************************
1572 * Write the user key to the hard disk so that it can be reused later or used
1573 * on operating systems other than Win32.
1574 *****************************************************************************/
1575 static int WriteUserKey( void *_p_drms, uint32_t *p_user_key )
1577 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1580 char psz_path[ PATH_MAX ];
1582 snprintf( psz_path, PATH_MAX - 1,
1583 "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
1585 #if defined( HAVE_ERRNO_H )
1586 # if defined( WIN32 )
1587 if( !mkdir( psz_path ) || errno == EEXIST )
1589 if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
1592 if( !mkdir( psz_path ) )
1595 snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d",
1596 p_drms->psz_homedir, p_drms->i_user, p_drms->i_key );
1598 file = utf8_fopen( psz_path, "wb" );
1601 i_ret = fwrite( p_user_key, sizeof(uint32_t),
1602 4, file ) == 4 ? 0 : -1;
1610 /*****************************************************************************
1611 * ReadUserKey: read the user key from hard disk
1612 *****************************************************************************
1613 * Retrieve the user key from the hard disk if available.
1614 *****************************************************************************/
1615 static int ReadUserKey( void *_p_drms, uint32_t *p_user_key )
1617 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1620 char psz_path[ PATH_MAX ];
1622 snprintf( psz_path, PATH_MAX - 1,
1623 "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir,
1624 p_drms->i_user, p_drms->i_key );
1626 file = utf8_fopen( psz_path, "rb" );
1629 i_ret = fread( p_user_key, sizeof(uint32_t),
1630 4, file ) == 4 ? 0 : -1;
1637 /*****************************************************************************
1638 * GetUserKey: get the user key
1639 *****************************************************************************
1640 * Retrieve the user key from the hard disk if available, otherwise generate
1641 * it from the system key. If the key could be successfully generated, write
1642 * it to the hard disk for future use.
1643 *****************************************************************************/
1644 static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
1646 static const char p_secret7[] = "mUfnpognadfgf873";
1647 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1649 struct shuffle_s shuffle;
1651 uint32_t *p_sci_data = NULL;
1652 uint32_t i_user, i_key;
1653 uint32_t p_sys_key[ 4 ];
1654 uint32_t i_sci_size = 0, i_blocks, i_remaining;
1655 uint32_t *p_sci0, *p_sci1, *p_buffer;
1656 uint32_t p_sci_key[ 4 ];
1660 if( ReadUserKey( p_drms, p_user_key ) == 0 )
1662 REVERSE( p_user_key, 4 );
1666 psz_ipod = getenv( "IPOD" );
1668 if( GetSystemKey( p_sys_key, psz_ipod ? true : false ) )
1673 if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
1678 /* Phase 1: unscramble the SCI data using the system key and shuffle
1679 * it using DoShuffle(). */
1681 /* Skip the first 4 bytes (some sort of header). Decrypt the rest. */
1682 i_blocks = (i_sci_size - 4) / 16;
1683 i_remaining = (i_sci_size - 4) - (i_blocks * 16);
1684 p_buffer = p_sci_data + 1;
1686 /* Decrypt and shuffle our data at the same time */
1687 InitAES( &aes, p_sys_key );
1688 REVERSE( p_sys_key, 4 );
1689 REVERSE( p_sci_data, 1 );
1690 InitShuffle( &shuffle, p_sys_key, p_sci_data[ 0 ] );
1692 memcpy( p_sci_key, p_secret7, 16 );
1693 REVERSE( p_sci_key, 4 );
1697 uint32_t p_tmp[ 4 ];
1699 REVERSE( p_buffer, 4 );
1700 DecryptAES( &aes, p_tmp, p_buffer );
1701 BlockXOR( p_tmp, p_sci_key, p_tmp );
1703 /* Use the previous scrambled data as the key for next block */
1704 memcpy( p_sci_key, p_buffer, 16 );
1706 /* Shuffle the decrypted data using a custom routine */
1707 DoShuffle( &shuffle, p_tmp, 4 );
1709 /* Copy this block back to p_buffer */
1710 memcpy( p_buffer, p_tmp, 16 );
1715 if( i_remaining >= 4 )
1717 REVERSE( p_buffer, i_remaining / 4 );
1718 DoShuffle( &shuffle, p_buffer, i_remaining / 4 );
1721 /* Phase 2: look for the user key in the generated data. I must admit I
1722 * do not understand what is going on here, because it almost
1723 * looks like we are browsing data that makes sense, even though
1724 * the DoShuffle() part made it completely meaningless. */
1727 REVERSE( p_sci_data + 5, 1 );
1728 i = U32_AT( p_sci_data + 5 );
1729 i_sci_size -= 22 * sizeof(uint32_t);
1730 p_sci1 = p_sci_data + 22;
1733 while( i_sci_size >= 20 && i > 0 )
1735 if( p_sci0 == NULL )
1737 i_sci_size -= 18 * sizeof(uint32_t);
1738 if( i_sci_size < 20 )
1744 REVERSE( p_sci1 + 17, 1 );
1745 y = U32_AT( p_sci1 + 17 );
1756 i_user = U32_AT( p_sci0 );
1757 i_key = U32_AT( p_sci1 );
1758 REVERSE( &i_user, 1 );
1759 REVERSE( &i_key, 1 );
1760 if( i_user == p_drms->i_user && ( ( i_key == p_drms->i_key ) ||
1761 ( !p_drms->i_key && ( p_sci1 == (p_sci0 + 18) ) ) ) )
1763 memcpy( p_user_key, p_sci1 + 1, 16 );
1764 REVERSE( p_sci1 + 1, 4 );
1765 WriteUserKey( p_drms, p_sci1 + 1 );
1772 i_sci_size -= 5 * sizeof(uint32_t);
1780 /*****************************************************************************
1781 * GetSCIData: get SCI data from "SC Info.sidb"
1782 *****************************************************************************
1783 * Read SCI data from "\Apple Computer\iTunes\SC Info\SC Info.sidb"
1784 *****************************************************************************/
1785 static int GetSCIData( char *psz_ipod, uint32_t **pp_sci,
1786 uint32_t *pi_sci_size )
1789 char *psz_path = NULL;
1790 char p_tmp[ 4 * PATH_MAX ];
1793 if( psz_ipod == NULL )
1796 const wchar_t *wfile =
1797 L"\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb";
1798 typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
1800 HINSTANCE shfolder_dll = NULL;
1801 SHGETFOLDERPATH dSHGetFolderPath = NULL;
1802 wchar_t wpath[PATH_MAX];
1804 if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
1807 (SHGETFOLDERPATH)GetProcAddress( shfolder_dll,
1808 _T("SHGetFolderPathW") );
1811 if( dSHGetFolderPath != NULL &&
1812 SUCCEEDED( dSHGetFolderPath( NULL, CSIDL_COMMON_APPDATA,
1813 NULL, 0, wpath ) ) )
1815 if (wcslen( wpath ) + wcslen( wfile ) >= PATH_MAX )
1819 wcscat( wpath, wfile );
1821 psz_path = FromWide( wpath );
1822 strncpy( p_tmp, psz_path, sizeof( p_tmp ) - 1 );
1823 p_tmp[sizeof( p_tmp ) - 1] = '\0';
1828 if( shfolder_dll != NULL )
1830 FreeLibrary( shfolder_dll );
1836 #define ISCINFO "iSCInfo"
1837 if( strstr( psz_ipod, ISCINFO ) == NULL )
1839 snprintf( p_tmp, sizeof(p_tmp) - 1,
1840 "%s/iPod_Control/iTunes/" ISCINFO "2", psz_ipod );
1845 psz_path = psz_ipod;
1849 if( psz_path == NULL )
1854 file = utf8_fopen( psz_path, "rb" );
1859 if( !fstat( fileno( file ), &st ) && st.st_size >= 4 )
1861 *pp_sci = malloc( st.st_size );
1862 if( *pp_sci != NULL )
1864 if( fread( *pp_sci, 1, st.st_size,
1865 file ) == (size_t)st.st_size )
1867 *pi_sci_size = st.st_size;
1872 free( (void *)*pp_sci );
1884 /*****************************************************************************
1885 * HashSystemInfo: hash system information
1886 *****************************************************************************
1887 * This function computes the MD5 hash of the C: hard drive serial number,
1888 * BIOS version, CPU type and Windows version.
1889 *****************************************************************************/
1890 static int HashSystemInfo( uint32_t *p_system_hash )
1902 static const LPCTSTR p_reg_keys[ 3 ][ 2 ] =
1905 _T("HARDWARE\\DESCRIPTION\\System"),
1906 _T("SystemBiosVersion")
1910 _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
1911 _T("ProcessorNameString")
1915 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
1922 AddMD5( &md5, "cache-control", 13 );
1923 AddMD5( &md5, "Ethernet", 8 );
1925 GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
1926 NULL, NULL, NULL, 0 );
1927 AddMD5( &md5, (const uint8_t *)&i_serial, 4 );
1929 for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
1931 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
1932 0, KEY_READ, &i_key ) != ERROR_SUCCESS )
1937 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1938 NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
1940 RegCloseKey( i_key );
1944 p_reg_buf = malloc( i_size );
1946 if( p_reg_buf != NULL )
1948 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1949 NULL, NULL, p_reg_buf,
1950 &i_size ) == ERROR_SUCCESS )
1952 AddMD5( &md5, (const uint8_t *)p_reg_buf, i_size );
1958 RegCloseKey( i_key );
1967 memcpy( p_system_hash, md5.p_digest, 16 );
1972 /*****************************************************************************
1973 * GetiPodID: Get iPod ID
1974 *****************************************************************************
1975 * This function gets the iPod ID.
1976 *****************************************************************************/
1977 static int GetiPodID( int64_t *p_ipod_id )
1981 #define PROD_NAME "iPod"
1982 #define VENDOR_NAME "Apple Computer, Inc."
1984 char *psz_ipod_id = getenv( "IPODID" );
1985 if( psz_ipod_id != NULL )
1987 *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
1995 io_iterator_t iterator;
1996 CFMutableDictionaryRef match_dic;
1997 CFMutableDictionaryRef smatch_dic;
1999 if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
2001 smatch_dic = IOServiceMatching( "IOFireWireUnit" );
2002 match_dic = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
2003 &kCFTypeDictionaryKeyCallBacks,
2004 &kCFTypeDictionaryValueCallBacks );
2006 if( smatch_dic != NULL && match_dic != NULL )
2008 CFDictionarySetValue( smatch_dic,
2009 CFSTR("FireWire Vendor Name"),
2010 CFSTR(VENDOR_NAME) );
2011 CFDictionarySetValue( smatch_dic,
2012 CFSTR("FireWire Product Name"),
2015 CFDictionarySetValue( match_dic,
2016 CFSTR(kIOPropertyMatchKey),
2019 if( IOServiceGetMatchingServices( port, match_dic,
2020 &iterator ) == KERN_SUCCESS )
2022 while( ( device = IOIteratorNext( iterator ) ) != NULL )
2024 value = IORegistryEntryCreateCFProperty( device,
2025 CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );
2029 if( CFGetTypeID( value ) == CFNumberGetTypeID() )
2032 CFNumberGetValue( (CFNumberRef)value,
2033 kCFNumberLongLongType,
2035 *p_ipod_id = i_ipod_id;
2042 IOObjectRelease( device );
2047 IOObjectRelease( iterator );
2049 CFRelease( match_dic );
2052 mach_port_deallocate( mach_task_self(), port );
2055 #elif defined (HAVE_SYSFS_LIBSYSFS_H)
2056 struct sysfs_bus *bus = NULL;
2057 struct dlist *devlist = NULL;
2058 struct dlist *attributes = NULL;
2059 struct sysfs_device *curdev = NULL;
2060 struct sysfs_attribute *curattr = NULL;
2062 bus = sysfs_open_bus( "ieee1394" );
2065 devlist = sysfs_get_bus_devices( bus );
2066 if( devlist != NULL )
2068 dlist_for_each_data( devlist, curdev, struct sysfs_device )
2070 attributes = sysfs_get_device_attributes( curdev );
2071 if( attributes != NULL )
2073 dlist_for_each_data( attributes, curattr,
2074 struct sysfs_attribute )
2076 if( ( strcmp( curattr->name, "model_name" ) == 0 ) &&
2077 ( strncmp( curattr->value, PROD_NAME,
2078 sizeof(PROD_NAME) ) == 0 ) )
2080 *p_ipod_id = strtoll( curdev->name, NULL, 16 );
2091 sysfs_close_bus( bus );
2098 #else /* !defined( UNDER_CE ) */
2100 void *drms_alloc( const char *psz_homedir ){ return 0; }
2101 void drms_free( void *a ){}
2102 void drms_decrypt( void *a, uint32_t *b, uint32_t c, uint32_t *k ){}
2103 void drms_get_p_key( void *p_drms, uint32_t *p_key );
2104 int drms_init( void *a, uint32_t b, uint8_t *c, uint32_t d ){ return -1; }
2106 #endif /* defined( UNDER_CE ) */