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 *****************************************************************************/
40 # include <vlc_charset.h>
50 # if !defined( UNDER_CE )
58 #ifdef HAVE_SYS_STAT_H
59 # include <sys/stat.h>
61 #ifdef HAVE_SYS_TYPES_H
62 # include <sys/types.h>
65 /* In Solaris (and perhaps others) PATH_MAX is in limits.h. */
69 # include <mach/mach.h>
70 # include <IOKit/IOKitLib.h>
71 # include <CoreFoundation/CFNumber.h>
74 #ifdef HAVE_SYSFS_LIBSYSFS_H
75 # include <sysfs/libsysfs.h>
79 #include "drmstables.h"
81 #if !defined( UNDER_CE )
82 /*****************************************************************************
83 * aes_s: AES keys structure
84 *****************************************************************************
85 * This structure stores a set of keys usable for encryption and decryption
86 * with the AES/Rijndael algorithm.
87 *****************************************************************************/
90 uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
91 uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
95 # define Digest DigestMD5
97 /*****************************************************************************
98 * md5_s: MD5 message structure
99 *****************************************************************************
100 * This structure stores the static information needed to compute an MD5
101 * hash. It has an extra data buffer to allow non-aligned writes.
102 *****************************************************************************/
105 uint64_t i_bits; /* Total written bits */
106 uint32_t p_digest[4]; /* The MD5 digest */
107 uint32_t p_data[16]; /* Buffer to cache non-aligned writes */
111 /*****************************************************************************
112 * shuffle_s: shuffle structure
113 *****************************************************************************
114 * This structure stores the static information needed to shuffle data using
115 * a custom algorithm.
116 *****************************************************************************/
120 uint32_t p_commands[ 20 ];
121 uint32_t p_bordel[ 16 ];
124 #define SWAP( a, b ) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
126 /*****************************************************************************
127 * drms_s: DRMS structure
128 *****************************************************************************
129 * This structure stores the static information needed to decrypt DRMS data.
130 *****************************************************************************/
135 uint8_t p_iviv[ 16 ];
141 char psz_homedir[ PATH_MAX ];
144 /*****************************************************************************
146 *****************************************************************************/
147 static void InitAES ( struct aes_s *, uint32_t * );
148 static void DecryptAES ( struct aes_s *, uint32_t *, const uint32_t * );
151 static void InitMD5 ( struct md5_s * );
152 static void AddMD5 ( struct md5_s *, const uint8_t *, uint32_t );
153 static void EndMD5 ( struct md5_s * );
154 static void Digest ( struct md5_s *, uint32_t * );
157 static void InitShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
158 static void DoShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
160 static uint32_t FirstPass ( uint32_t * );
161 static void SecondPass ( uint32_t *, uint32_t );
162 static void ThirdPass ( uint32_t * );
163 static void FourthPass ( uint32_t * );
164 static void TinyShuffle1 ( uint32_t * );
165 static void TinyShuffle2 ( uint32_t * );
166 static void TinyShuffle3 ( uint32_t * );
167 static void TinyShuffle4 ( uint32_t * );
168 static void TinyShuffle5 ( uint32_t * );
169 static void TinyShuffle6 ( uint32_t * );
170 static void TinyShuffle7 ( uint32_t * );
171 static void TinyShuffle8 ( uint32_t * );
172 static void DoExtShuffle ( uint32_t * );
174 static int GetSystemKey ( uint32_t *, vlc_bool_t );
175 static int WriteUserKey ( void *, uint32_t * );
176 static int ReadUserKey ( void *, uint32_t * );
177 static int GetUserKey ( void *, uint32_t * );
179 static int GetSCIData ( char *, uint32_t **, uint32_t * );
180 static int HashSystemInfo ( uint32_t * );
181 static int GetiPodID ( int64_t * );
183 #ifdef WORDS_BIGENDIAN
184 /*****************************************************************************
185 * Reverse: reverse byte order
186 *****************************************************************************/
187 static inline void Reverse( uint32_t *p_buffer, int n )
191 for( i = 0; i < n; i++ )
193 p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
196 # define REVERSE( p, n ) Reverse( p, n )
198 # define REVERSE( p, n )
201 /*****************************************************************************
202 * BlockXOR: XOR two 128 bit blocks
203 *****************************************************************************/
204 static inline void BlockXOR( uint32_t *p_dest, uint32_t *p_s1, uint32_t *p_s2 )
208 for( i = 0; i < 4; i++ )
210 p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
214 /*****************************************************************************
215 * drms_alloc: allocate a DRMS structure
216 *****************************************************************************/
217 void *drms_alloc( char *psz_homedir )
219 struct drms_s *p_drms;
221 p_drms = malloc( sizeof(struct drms_s) );
228 memset( p_drms, 0, sizeof(struct drms_s) );
230 strncpy( p_drms->psz_homedir, psz_homedir, PATH_MAX );
231 p_drms->psz_homedir[ PATH_MAX - 1 ] = '\0';
233 return (void *)p_drms;
236 /*****************************************************************************
237 * drms_free: free a previously allocated DRMS structure
238 *****************************************************************************/
239 void drms_free( void *_p_drms )
241 struct drms_s *p_drms = (struct drms_s *)_p_drms;
243 if( p_drms->p_name != NULL )
245 free( (void *)p_drms->p_name );
251 /*****************************************************************************
252 * drms_decrypt: unscramble a chunk of data
253 *****************************************************************************/
254 void drms_decrypt( void *_p_drms, uint32_t *p_buffer, uint32_t i_bytes )
256 struct drms_s *p_drms = (struct drms_s *)_p_drms;
258 unsigned int i_blocks;
260 /* AES is a block cypher, round down the byte count */
261 i_blocks = i_bytes / 16;
262 i_bytes = i_blocks * 16;
264 /* Initialise the key */
265 memcpy( p_key, p_drms->p_key, 16 );
272 REVERSE( p_buffer, 4 );
273 DecryptAES( &p_drms->aes, p_tmp, p_buffer );
274 BlockXOR( p_tmp, p_key, p_tmp );
276 /* Use the previous scrambled data as the key for next block */
277 memcpy( p_key, p_buffer, 16 );
279 /* Copy unscrambled data back to the buffer */
280 memcpy( p_buffer, p_tmp, 16 );
281 REVERSE( p_buffer, 4 );
287 /*****************************************************************************
288 * drms_init: initialise a DRMS structure
289 *****************************************************************************
293 * -2: invalid argument
294 * -3: could not get system key
295 * -4: could not get SCI data
296 * -5: no user key found in SCI data
297 * -6: invalid user key
298 *****************************************************************************/
299 int drms_init( void *_p_drms, uint32_t i_type,
300 uint8_t *p_info, uint32_t i_len )
302 struct drms_s *p_drms = (struct drms_s *)_p_drms;
308 if( i_len < sizeof(p_drms->i_user) )
314 p_drms->i_user = U32_AT( p_info );
318 if( i_len < sizeof(p_drms->i_key) )
324 p_drms->i_key = U32_AT( p_info );
328 if( i_len < sizeof(p_drms->p_key) )
334 memcpy( p_drms->p_iviv, p_info, 16 );
338 p_drms->p_name = (uint8_t*) strdup( (char *)p_info );
340 if( p_drms->p_name == NULL )
348 uint32_t p_priv[ 64 ];
358 AddMD5( &md5, p_drms->p_name, strlen( (char *)p_drms->p_name ) );
359 AddMD5( &md5, p_drms->p_iviv, 16 );
362 if( p_drms->i_user == 0 && p_drms->i_key == 0 )
364 static char const p_secret[] = "tr1-th3n.y00_by3";
365 memcpy( p_drms->p_key, p_secret, 16 );
366 REVERSE( p_drms->p_key, 4 );
370 i_ret = GetUserKey( p_drms, p_drms->p_key );
377 InitAES( &p_drms->aes, p_drms->p_key );
379 memcpy( p_priv, p_info, 64 );
380 memcpy( p_drms->p_key, md5.p_digest, 16 );
381 drms_decrypt( p_drms, p_priv, 64 );
382 REVERSE( p_priv, 64 );
384 if( p_priv[ 0 ] != 0x6e757469 ) /* itun */
390 InitAES( &p_drms->aes, p_priv + 6 );
391 memcpy( p_drms->p_key, p_priv + 12, 16 );
393 free( (void *)p_drms->p_name );
394 p_drms->p_name = NULL;
402 /* The following functions are local */
404 /*****************************************************************************
405 * InitAES: initialise AES/Rijndael encryption/decryption tables
406 *****************************************************************************
407 * The Advanced Encryption Standard (AES) is described in RFC 3268
408 *****************************************************************************/
409 static void InitAES( struct aes_s *p_aes, uint32_t *p_key )
412 uint32_t i_key, i_seed;
414 memset( p_aes->pp_enc_keys[1], 0, 16 );
415 memcpy( p_aes->pp_enc_keys[0], p_key, 16 );
417 /* Generate the key tables */
418 i_seed = p_aes->pp_enc_keys[ 0 ][ 3 ];
420 for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
424 i_seed = AES_ROR( i_seed, 8 );
426 j = p_aes_table[ i_key ];
428 j ^= p_aes_encrypt[ (i_seed >> 24) & 0xff ]
429 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 16) & 0xff ], 8 )
430 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 8) & 0xff ], 16 )
431 ^ AES_ROR( p_aes_encrypt[ i_seed & 0xff ], 24 );
433 j ^= p_aes->pp_enc_keys[ i_key ][ 0 ];
434 p_aes->pp_enc_keys[ i_key + 1 ][ 0 ] = j;
435 j ^= p_aes->pp_enc_keys[ i_key ][ 1 ];
436 p_aes->pp_enc_keys[ i_key + 1 ][ 1 ] = j;
437 j ^= p_aes->pp_enc_keys[ i_key ][ 2 ];
438 p_aes->pp_enc_keys[ i_key + 1 ][ 2 ] = j;
439 j ^= p_aes->pp_enc_keys[ i_key ][ 3 ];
440 p_aes->pp_enc_keys[ i_key + 1 ][ 3 ] = j;
445 memcpy( p_aes->pp_dec_keys[ 0 ],
446 p_aes->pp_enc_keys[ 0 ], 16 );
448 for( i = 1; i < AES_KEY_COUNT; i++ )
450 for( t = 0; t < 4; t++ )
452 uint32_t j, k, l, m, n;
454 j = p_aes->pp_enc_keys[ i ][ t ];
456 k = (((j >> 7) & 0x01010101) * 27) ^ ((j & 0xff7f7f7f) << 1);
457 l = (((k >> 7) & 0x01010101) * 27) ^ ((k & 0xff7f7f7f) << 1);
458 m = (((l >> 7) & 0x01010101) * 27) ^ ((l & 0xff7f7f7f) << 1);
462 n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
464 p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
469 /*****************************************************************************
470 * DecryptAES: decrypt an AES/Rijndael 128 bit block
471 *****************************************************************************/
472 static void DecryptAES( struct aes_s *p_aes,
473 uint32_t *p_dest, const uint32_t *p_src )
475 uint32_t p_wtxt[ 4 ]; /* Working cyphertext */
477 unsigned int i_round, t;
479 for( t = 0; t < 4; t++ )
481 /* FIXME: are there any endianness issues here? */
482 p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
486 for( i_round = 0; i_round < (AES_KEY_COUNT - 1); i_round++ )
488 for( t = 0; t < 4; t++ )
490 p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
493 for( t = 0; t < 4; t++ )
495 p_wtxt[ t ] = p_tmp[ t ]
496 ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - i_round ][ t ];
500 /* Final round (9) */
501 for( t = 0; t < 4; t++ )
503 p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
504 p_dest[ t ] ^= p_aes->pp_dec_keys[ 0 ][ t ];
509 /*****************************************************************************
510 * InitMD5: initialise an MD5 message
511 *****************************************************************************
512 * The MD5 message-digest algorithm is described in RFC 1321
513 *****************************************************************************/
514 static void InitMD5( struct md5_s *p_md5 )
516 p_md5->p_digest[ 0 ] = 0x67452301;
517 p_md5->p_digest[ 1 ] = 0xefcdab89;
518 p_md5->p_digest[ 2 ] = 0x98badcfe;
519 p_md5->p_digest[ 3 ] = 0x10325476;
521 memset( p_md5->p_data, 0, 64 );
525 /*****************************************************************************
526 * AddMD5: add i_len bytes to an MD5 message
527 *****************************************************************************/
528 static void AddMD5( struct md5_s *p_md5, const uint8_t *p_src, uint32_t i_len )
530 unsigned int i_current; /* Current bytes in the spare buffer */
531 unsigned int i_offset = 0;
533 i_current = (p_md5->i_bits / 8) & 63;
535 p_md5->i_bits += 8 * i_len;
537 /* If we can complete our spare buffer to 64 bytes, do it and add the
538 * resulting buffer to the MD5 message */
539 if( i_len >= (64 - i_current) )
541 memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src,
543 Digest( p_md5, p_md5->p_data );
545 i_offset += (64 - i_current);
546 i_len -= (64 - i_current);
550 /* Add as many entire 64 bytes blocks as we can to the MD5 message */
553 uint32_t p_tmp[ 16 ];
554 memcpy( p_tmp, p_src + i_offset, 64 );
555 Digest( p_md5, p_tmp );
560 /* Copy our remaining data to the message's spare buffer */
561 memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src + i_offset, i_len );
564 /*****************************************************************************
565 * EndMD5: finish an MD5 message
566 *****************************************************************************
567 * This function adds adequate padding to the end of the message, and appends
568 * the bit count so that we end at a block boundary.
569 *****************************************************************************/
570 static void EndMD5( struct md5_s *p_md5 )
572 unsigned int i_current;
574 i_current = (p_md5->i_bits / 8) & 63;
576 /* Append 0x80 to our buffer. No boundary check because the temporary
577 * buffer cannot be full, otherwise AddMD5 would have emptied it. */
578 ((uint8_t *)p_md5->p_data)[ i_current++ ] = 0x80;
580 /* If less than 8 bytes are available at the end of the block, complete
581 * this 64 bytes block with zeros and add it to the message. We'll add
582 * our length at the end of the next block. */
585 memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (64 - i_current) );
586 Digest( p_md5, p_md5->p_data );
590 /* Fill the unused space in our last block with zeroes and put the
591 * message length at the end. */
592 memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (56 - i_current) );
593 p_md5->p_data[ 14 ] = p_md5->i_bits & 0xffffffff;
594 p_md5->p_data[ 15 ] = (p_md5->i_bits >> 32);
595 REVERSE( &p_md5->p_data[ 14 ], 2 );
597 Digest( p_md5, p_md5->p_data );
600 #define F1( x, y, z ) ((z) ^ ((x) & ((y) ^ (z))))
601 #define F2( x, y, z ) F1((z), (x), (y))
602 #define F3( x, y, z ) ((x) ^ (y) ^ (z))
603 #define F4( x, y, z ) ((y) ^ ((x) | ~(z)))
605 #define MD5_DO( f, w, x, y, z, data, s ) \
606 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
608 /*****************************************************************************
609 * Digest: update the MD5 digest with 64 bytes of data
610 *****************************************************************************/
611 static void Digest( struct md5_s *p_md5, uint32_t *p_input )
615 REVERSE( p_input, 16 );
617 a = p_md5->p_digest[ 0 ];
618 b = p_md5->p_digest[ 1 ];
619 c = p_md5->p_digest[ 2 ];
620 d = p_md5->p_digest[ 3 ];
622 MD5_DO( F1, a, b, c, d, p_input[ 0 ] + 0xd76aa478, 7 );
623 MD5_DO( F1, d, a, b, c, p_input[ 1 ] + 0xe8c7b756, 12 );
624 MD5_DO( F1, c, d, a, b, p_input[ 2 ] + 0x242070db, 17 );
625 MD5_DO( F1, b, c, d, a, p_input[ 3 ] + 0xc1bdceee, 22 );
626 MD5_DO( F1, a, b, c, d, p_input[ 4 ] + 0xf57c0faf, 7 );
627 MD5_DO( F1, d, a, b, c, p_input[ 5 ] + 0x4787c62a, 12 );
628 MD5_DO( F1, c, d, a, b, p_input[ 6 ] + 0xa8304613, 17 );
629 MD5_DO( F1, b, c, d, a, p_input[ 7 ] + 0xfd469501, 22 );
630 MD5_DO( F1, a, b, c, d, p_input[ 8 ] + 0x698098d8, 7 );
631 MD5_DO( F1, d, a, b, c, p_input[ 9 ] + 0x8b44f7af, 12 );
632 MD5_DO( F1, c, d, a, b, p_input[ 10 ] + 0xffff5bb1, 17 );
633 MD5_DO( F1, b, c, d, a, p_input[ 11 ] + 0x895cd7be, 22 );
634 MD5_DO( F1, a, b, c, d, p_input[ 12 ] + 0x6b901122, 7 );
635 MD5_DO( F1, d, a, b, c, p_input[ 13 ] + 0xfd987193, 12 );
636 MD5_DO( F1, c, d, a, b, p_input[ 14 ] + 0xa679438e, 17 );
637 MD5_DO( F1, b, c, d, a, p_input[ 15 ] + 0x49b40821, 22 );
639 MD5_DO( F2, a, b, c, d, p_input[ 1 ] + 0xf61e2562, 5 );
640 MD5_DO( F2, d, a, b, c, p_input[ 6 ] + 0xc040b340, 9 );
641 MD5_DO( F2, c, d, a, b, p_input[ 11 ] + 0x265e5a51, 14 );
642 MD5_DO( F2, b, c, d, a, p_input[ 0 ] + 0xe9b6c7aa, 20 );
643 MD5_DO( F2, a, b, c, d, p_input[ 5 ] + 0xd62f105d, 5 );
644 MD5_DO( F2, d, a, b, c, p_input[ 10 ] + 0x02441453, 9 );
645 MD5_DO( F2, c, d, a, b, p_input[ 15 ] + 0xd8a1e681, 14 );
646 MD5_DO( F2, b, c, d, a, p_input[ 4 ] + 0xe7d3fbc8, 20 );
647 MD5_DO( F2, a, b, c, d, p_input[ 9 ] + 0x21e1cde6, 5 );
648 MD5_DO( F2, d, a, b, c, p_input[ 14 ] + 0xc33707d6, 9 );
649 MD5_DO( F2, c, d, a, b, p_input[ 3 ] + 0xf4d50d87, 14 );
650 MD5_DO( F2, b, c, d, a, p_input[ 8 ] + 0x455a14ed, 20 );
651 MD5_DO( F2, a, b, c, d, p_input[ 13 ] + 0xa9e3e905, 5 );
652 MD5_DO( F2, d, a, b, c, p_input[ 2 ] + 0xfcefa3f8, 9 );
653 MD5_DO( F2, c, d, a, b, p_input[ 7 ] + 0x676f02d9, 14 );
654 MD5_DO( F2, b, c, d, a, p_input[ 12 ] + 0x8d2a4c8a, 20 );
656 MD5_DO( F3, a, b, c, d, p_input[ 5 ] + 0xfffa3942, 4 );
657 MD5_DO( F3, d, a, b, c, p_input[ 8 ] + 0x8771f681, 11 );
658 MD5_DO( F3, c, d, a, b, p_input[ 11 ] + 0x6d9d6122, 16 );
659 MD5_DO( F3, b, c, d, a, p_input[ 14 ] + 0xfde5380c, 23 );
660 MD5_DO( F3, a, b, c, d, p_input[ 1 ] + 0xa4beea44, 4 );
661 MD5_DO( F3, d, a, b, c, p_input[ 4 ] + 0x4bdecfa9, 11 );
662 MD5_DO( F3, c, d, a, b, p_input[ 7 ] + 0xf6bb4b60, 16 );
663 MD5_DO( F3, b, c, d, a, p_input[ 10 ] + 0xbebfbc70, 23 );
664 MD5_DO( F3, a, b, c, d, p_input[ 13 ] + 0x289b7ec6, 4 );
665 MD5_DO( F3, d, a, b, c, p_input[ 0 ] + 0xeaa127fa, 11 );
666 MD5_DO( F3, c, d, a, b, p_input[ 3 ] + 0xd4ef3085, 16 );
667 MD5_DO( F3, b, c, d, a, p_input[ 6 ] + 0x04881d05, 23 );
668 MD5_DO( F3, a, b, c, d, p_input[ 9 ] + 0xd9d4d039, 4 );
669 MD5_DO( F3, d, a, b, c, p_input[ 12 ] + 0xe6db99e5, 11 );
670 MD5_DO( F3, c, d, a, b, p_input[ 15 ] + 0x1fa27cf8, 16 );
671 MD5_DO( F3, b, c, d, a, p_input[ 2 ] + 0xc4ac5665, 23 );
673 MD5_DO( F4, a, b, c, d, p_input[ 0 ] + 0xf4292244, 6 );
674 MD5_DO( F4, d, a, b, c, p_input[ 7 ] + 0x432aff97, 10 );
675 MD5_DO( F4, c, d, a, b, p_input[ 14 ] + 0xab9423a7, 15 );
676 MD5_DO( F4, b, c, d, a, p_input[ 5 ] + 0xfc93a039, 21 );
677 MD5_DO( F4, a, b, c, d, p_input[ 12 ] + 0x655b59c3, 6 );
678 MD5_DO( F4, d, a, b, c, p_input[ 3 ] + 0x8f0ccc92, 10 );
679 MD5_DO( F4, c, d, a, b, p_input[ 10 ] + 0xffeff47d, 15 );
680 MD5_DO( F4, b, c, d, a, p_input[ 1 ] + 0x85845dd1, 21 );
681 MD5_DO( F4, a, b, c, d, p_input[ 8 ] + 0x6fa87e4f, 6 );
682 MD5_DO( F4, d, a, b, c, p_input[ 15 ] + 0xfe2ce6e0, 10 );
683 MD5_DO( F4, c, d, a, b, p_input[ 6 ] + 0xa3014314, 15 );
684 MD5_DO( F4, b, c, d, a, p_input[ 13 ] + 0x4e0811a1, 21 );
685 MD5_DO( F4, a, b, c, d, p_input[ 4 ] + 0xf7537e82, 6 );
686 MD5_DO( F4, d, a, b, c, p_input[ 11 ] + 0xbd3af235, 10 );
687 MD5_DO( F4, c, d, a, b, p_input[ 2 ] + 0x2ad7d2bb, 15 );
688 MD5_DO( F4, b, c, d, a, p_input[ 9 ] + 0xeb86d391, 21 );
690 p_md5->p_digest[ 0 ] += a;
691 p_md5->p_digest[ 1 ] += b;
692 p_md5->p_digest[ 2 ] += c;
693 p_md5->p_digest[ 3 ] += d;
697 /*****************************************************************************
698 * InitShuffle: initialise a shuffle structure
699 *****************************************************************************
700 * This function initialises tables in the p_shuffle structure that will be
701 * used later by DoShuffle. The only external parameter is p_sys_key.
702 *****************************************************************************/
703 static void InitShuffle( struct shuffle_s *p_shuffle, uint32_t *p_sys_key,
706 char p_secret1[] = "Tv!*";
707 static char const p_secret2[] = "____v8rhvsaAvOKM____FfUH%798=[;."
708 "____f8677680a634____ba87fnOIf)(*";
711 p_shuffle->i_version = i_version;
713 /* Fill p_commands using the key and a secret seed */
714 for( i = 0; i < 20; i++ )
720 AddMD5( &md5, (const uint8_t *)p_sys_key, 16 );
721 AddMD5( &md5, (const uint8_t *)p_secret1, 4 );
726 REVERSE( md5.p_digest, 1 );
727 i_hash = ((int32_t)U32_AT(md5.p_digest)) % 1024;
729 p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
732 /* Fill p_bordel with completely meaningless initial values. */
733 memcpy( p_shuffle->p_bordel, p_secret2, 64 );
734 for( i = 0; i < 4; i++ )
736 p_shuffle->p_bordel[ 4 * i ] = U32_AT(p_sys_key + i);
737 REVERSE( p_shuffle->p_bordel + 4 * i + 1, 3 );
741 /*****************************************************************************
742 * DoShuffle: shuffle buffer
743 *****************************************************************************
744 * This is so ugly and uses so many MD5 checksums that it is most certainly
745 * one-way, though why it needs to be so complicated is beyond me.
746 *****************************************************************************/
747 static void DoShuffle( struct shuffle_s *p_shuffle,
748 uint32_t *p_buffer, uint32_t i_size )
751 uint32_t p_big_bordel[ 16 ];
752 uint32_t *p_bordel = p_shuffle->p_bordel;
755 static uint32_t i_secret = 0;
757 static 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
768 static char p_secret4[] =
769 "pbclevtug (p) Nccyr Pbzchgre, Vap. Nyy Evtugf Erfreirq.";
773 REVERSE( p_secret3, sizeof(p_secret3)/sizeof(p_secret3[ 0 ]) );
774 for( ; p_secret4[ i_secret ] != '\0'; i_secret++ )
776 #define ROT13(c) (((c)>='A'&&(c)<='Z')?(((c)-'A'+13)%26)+'A':\
777 ((c)>='a'&&(c)<='z')?(((c)-'a'+13)%26)+'a':c)
778 p_secret4[ i_secret ] = ROT13(p_secret4[ i_secret ]);
780 i_secret++; /* include zero terminator */
783 /* Using the MD5 hash of a memory block is probably not one-way enough
784 * for the iTunes people. This function randomises p_bordel depending on
785 * the values in p_commands to make things even more messy in p_bordel. */
786 for( i = 0; i < 20; i++ )
788 uint8_t i_command, i_index;
790 if( !p_shuffle->p_commands[ i ] )
795 i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
796 i_index = p_shuffle->p_commands[ i ] & 0xff;
801 p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
802 + p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
805 p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
808 p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
811 p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
816 if( p_shuffle->i_version == 0x01000300 )
818 DoExtShuffle( p_bordel );
821 /* Convert our newly randomised p_bordel to big endianness and take
824 for( i = 0; i < 16; i++ )
826 p_big_bordel[ i ] = U32_AT(p_bordel + i);
828 AddMD5( &md5, (const uint8_t *)p_big_bordel, 64 );
829 if( p_shuffle->i_version == 0x01000300 )
831 AddMD5( &md5, (const uint8_t *)p_secret3, sizeof(p_secret3) );
832 AddMD5( &md5, (const uint8_t *)p_secret4, i_secret );
836 /* XOR our buffer with the computed checksum */
837 for( i = 0; i < i_size; i++ )
839 p_buffer[ i ] ^= md5.p_digest[ i ];
843 /*****************************************************************************
844 * DoExtShuffle: extended shuffle
845 *****************************************************************************
846 * This is even uglier.
847 *****************************************************************************/
848 static void DoExtShuffle( uint32_t * p_bordel )
852 i_ret = FirstPass( p_bordel );
854 SecondPass( p_bordel, i_ret );
856 ThirdPass( p_bordel );
858 FourthPass( p_bordel );
861 static uint32_t FirstPass( uint32_t * p_bordel )
863 uint32_t i, i_cmd, i_ret = 5;
865 TinyShuffle1( p_bordel );
871 p_bordel[ 1 ] += 0x10000000;
872 p_bordel[ 3 ] += 0x12777;
874 if( (p_bordel[ 10 ] & 1) && i_ret )
877 p_bordel[ 1 ] -= p_bordel[ 2 ];
878 p_bordel[ 11 ] += p_bordel[ 12 ];
882 if( (p_bordel[ 1 ] + p_bordel[ 2 ]) >= 0x7D0 )
884 switch( ((p_bordel[ 3 ] ^ 0x567F) >> 2) & 7 )
887 for( i = 0; i < 3; i++ )
889 if( p_bordel[ i + 10 ] > 0x4E20 )
891 p_bordel[ i + 1 ] += p_bordel[ i + 2 ];
896 p_bordel[ 1 ] -= p_bordel[ 2 ];
899 p_bordel[ 11 ] += p_bordel[ 12 ];
902 p_bordel[ 3 ] ^= p_bordel[ 4 ];
905 p_bordel[ 13 ] &= p_bordel[ 14 ];
908 p_bordel[ 0 ] |= p_bordel[ 1 ];
920 for( i = 0, i_cmd = 0; i < 16; i++ )
922 if( p_bordel[ i ] < p_bordel[ i_cmd ] )
928 if( i_ret && i_cmd != 5 )
936 p_bordel[ 8 ] &= p_bordel[ 6 ] >> 1;
940 for( i = 0; i < 3; i++ )
943 if( p_bordel[ 11 ] & 5 )
945 p_bordel[ 8 ] += p_bordel[ 9 ];
955 i_cmd = (p_bordel[ 15 ] + 0x93) >> 3;
956 if( p_bordel[ 15 ] & 0x100 )
965 while( p_bordel[ 11 ] & 1 )
967 p_bordel[ 11 ] >>= 1;
972 p_bordel[ 14 ] -= 0x19FE;
984 i_cmd = ((p_bordel[ 3 ] + p_bordel[ 4 ] + 10) >> 1) - p_bordel[ 4 ];
992 p_bordel[ 14 ] >>= 1;
1001 p_bordel[ 15 ] &= 0x55;
1004 p_bordel[ 2 ] &= 0xB62FC;
1010 TinyShuffle2( p_bordel );
1015 static void SecondPass( uint32_t * p_bordel, uint32_t i_tmp )
1017 uint32_t i, i_cmd, i_jc = 5;
1019 TinyShuffle3( p_bordel );
1021 for( i = 0, i_cmd = 0; i < 16; i++ )
1023 if( p_bordel[ i ] > p_bordel[ i_cmd ] )
1032 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
1038 if( (p_bordel[ 9 ] & 0x7777) == 0x3333 )
1045 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
1054 p_bordel[ 1 ] -= p_bordel[ 5 ];
1055 for( i = 0; i < 3; i++ )
1057 switch( p_bordel[ 1 ] & 3 )
1066 p_bordel[ 13 ] &= 0xFEFEFEF7;
1069 p_bordel[ 8 ] |= 0x80080011;
1081 p_bordel[ 15 ] ^= 0x18547EFF;
1087 switch( ( p_bordel[ 12 ] + p_bordel[ 13 ] + p_bordel[ 6 ] ) % 5 )
1090 p_bordel[ 12 ] -= 1;
1093 p_bordel[ 12 ] -= 1;
1094 p_bordel[ 13 ] += 1;
1097 p_bordel[ 13 ] += 4;
1100 p_bordel[ 12 ] -= 1;
1107 i = 3; /* Restart the whole loop */
1112 TinyShuffle4( p_bordel );
1116 TinyShuffle5( p_bordel );
1118 switch( ( p_bordel[ 2 ] * 2 + 15 ) % 5 )
1121 if( ( p_bordel[ 3 ] + i_tmp ) <=
1122 ( p_bordel[ 1 ] + p_bordel[ 15 ] ) )
1128 p_bordel[ 10 ] -= 0x13;
1131 p_bordel[ 5 ] >>= 2;
1135 if( !( p_bordel[ 2 ] & 1 ) || i_jc == 0 )
1141 p_bordel[ 2 ] += 0x13;
1142 p_bordel[ 12 ] += 1;
1145 p_bordel[ 2 ] &= 0x10076000;
1148 static void ThirdPass( uint32_t * p_bordel )
1152 i_cmd = ((p_bordel[ 7 ] + p_bordel[ 14 ] + 10) >> 1) - p_bordel[ 14 ];
1158 p_bordel[ 1 ] <<= 1;
1159 p_bordel[ 2 ] <<= 2;
1160 p_bordel[ 3 ] <<= 3;
1163 p_bordel[ i_cmd + 3 ] &= 0x5EDE36B;
1164 p_bordel[ 5 ] += p_bordel[ 8 ];
1165 p_bordel[ 4 ] += p_bordel[ 7 ];
1166 p_bordel[ 3 ] += p_bordel[ 6 ];
1167 p_bordel[ 2 ] += p_bordel[ 5 ];
1170 p_bordel[ 1 ] += p_bordel[ 4 ];
1171 p_bordel[ 0 ] += p_bordel[ 3 ];
1172 TinyShuffle6( p_bordel );
1173 return; /* jc = 4 */
1175 if( (p_bordel[ 11 ] & p_bordel[ 2 ]) > 0x211B )
1184 p_bordel[ 9 ] ^= p_bordel[ 2 ];
1187 p_bordel[ 2 ] ^= (p_bordel[ 1 ] & p_bordel[ 13 ]);
1190 p_bordel[ 0 ] -= p_bordel[ 11 ] & p_bordel[ 15 ];
1191 return; /* jc = 4 */
1193 p_bordel[ 6 ] >>= (p_bordel[ 14 ] & 3);
1197 SWAP( p_bordel[ 0 ], p_bordel[ 10 ] );
1199 TinyShuffle6( p_bordel );
1201 return; /* jc = 5 */
1204 static void FourthPass( uint32_t * p_bordel )
1208 TinyShuffle7( p_bordel );
1210 switch( p_bordel[ 5 ] % 5)
1216 p_bordel[ 11 ] ^= (p_bordel[ 3 ] + p_bordel[ 6 ] + p_bordel[ 8 ]);
1219 for( i = 4; i < 15 && (p_bordel[ i ] & 5) == 0; i++ )
1221 SWAP( p_bordel[ i ], p_bordel[ 15 - i ] );
1225 p_bordel[ 12 ] -= 1;
1226 p_bordel[ 13 ] += 1;
1227 p_bordel[ 2 ] -= 0x64;
1228 p_bordel[ 3 ] += 0x64;
1229 TinyShuffle8( p_bordel );
1233 for( i = 0, j = 0; i < 16; i++ )
1235 if( p_bordel[ i ] > p_bordel[ j ] )
1241 switch( p_bordel[ j ] % 100 )
1244 SWAP( p_bordel[ 0 ], p_bordel[ j ] );
1247 p_bordel[ 1 ] >>= 1;
1248 p_bordel[ 2 ] <<= 1;
1249 p_bordel[ 14 ] >>= 3;
1250 p_bordel[ 15 ] <<= 4;
1253 p_bordel[ j ] += p_bordel[ 13 ];
1256 p_bordel[ 1 ] += 0x20E;
1257 p_bordel[ 5 ] += 0x223D;
1258 p_bordel[ 13 ] -= 0x576;
1259 p_bordel[ 15 ] += 0x576;
1262 p_bordel[ 2 ] -= 0x64;
1263 p_bordel[ 3 ] += 0x64;
1264 p_bordel[ 12 ] -= 1;
1265 p_bordel[ 13 ] += 1;
1269 p_bordel[ j ] += p_bordel[ 13 ];
1273 TinyShuffle8( p_bordel );
1276 /*****************************************************************************
1277 * TinyShuffle[12345678]: tiny shuffle subroutines
1278 *****************************************************************************
1279 * These standalone functions are little helpers for the shuffling process.
1280 *****************************************************************************/
1281 static void TinyShuffle1( uint32_t * p_bordel )
1283 uint32_t i_cmd = (p_bordel[ 5 ] + 10) >> 2;
1285 if( p_bordel[ 5 ] > 0x7D0 )
1299 if( p_bordel[ 4 ] & 5 )
1301 p_bordel[ 1 ] ^= 0x4D;
1305 p_bordel[ 12 ] += 5;
1310 static void TinyShuffle2( uint32_t * p_bordel )
1314 for( i = 0, j = 0; i < 16; i++ )
1316 if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) )
1324 for( ; j < 15; j++ )
1326 p_bordel[ j ] += p_bordel[ j + 1 ];
1331 p_bordel[ 2 ] &= 0xB62FC;
1335 static void TinyShuffle3( uint32_t * p_bordel )
1337 uint32_t i_cmd = p_bordel[ 6 ] + 0x194B;
1339 if( p_bordel[ 6 ] > 0x2710 )
1347 p_bordel[ 3 ] += 0x19FE;
1350 p_bordel[ 7 ] -= p_bordel[ 3 ] >> 2;
1353 p_bordel[ 5 ] ^= 0x248A;
1358 static void TinyShuffle4( uint32_t * p_bordel )
1362 for( i = 0, j = 0; i < 16; i++ )
1364 if( p_bordel[ i ] < p_bordel[ j ] )
1370 if( (p_bordel[ j ] % (j + 1)) > 10 )
1373 p_bordel[ 2 ] += 0x13;
1374 p_bordel[ 12 ] += 1;
1378 static void TinyShuffle5( uint32_t * p_bordel )
1382 p_bordel[ 2 ] &= 0x7F3F;
1384 for( i = 0; i < 5; i++ )
1386 switch( ( p_bordel[ 2 ] + 10 + i ) % 5 )
1389 p_bordel[ 12 ] &= p_bordel[ 2 ];
1392 p_bordel[ 3 ] ^= p_bordel[ 15 ];
1395 p_bordel[ 15 ] += 0x576;
1398 p_bordel[ 7 ] -= 0x2D;
1401 p_bordel[ 1 ] <<= 1;
1407 static void TinyShuffle6( uint32_t * p_bordel )
1411 for( i = 0; i < 8; i++ )
1413 j = p_bordel[ 3 ] & 0x7514 ? 5 : 7;
1414 SWAP( p_bordel[ i ], p_bordel[ i + j ] );
1418 static void TinyShuffle7( uint32_t * p_bordel )
1422 i = (((p_bordel[ 9 ] + p_bordel[ 15 ] + 12) >> 2) - p_bordel[ 4 ]) & 7;
1426 SWAP( p_bordel[ i ], p_bordel[ i + 3 ] );
1429 SWAP( p_bordel[ 1 ], p_bordel[ 10 ] );
1432 static void TinyShuffle8( uint32_t * p_bordel )
1436 i = (p_bordel[ 0 ] & p_bordel[ 6 ]) & 0xF;
1438 switch( p_bordel[ i ] % 1000 )
1441 if( (p_bordel[ i ] & 0x777) > (p_bordel[ 7 ] & 0x5555) )
1443 p_bordel[ i ] ^= p_bordel[ 5 ] & p_bordel[ 3 ];
1447 p_bordel[ 15 ] &= 0x5555;
1450 p_bordel[ i ] ^= p_bordel[ 15 ];
1453 SWAP( p_bordel[ 0 ], p_bordel[ 3 ] );
1454 SWAP( p_bordel[ 1 ], p_bordel[ 6 ] );
1455 SWAP( p_bordel[ 3 ], p_bordel[ 6 ] );
1456 SWAP( p_bordel[ 4 ], p_bordel[ 9 ] );
1457 SWAP( p_bordel[ 5 ], p_bordel[ 8 ] );
1458 SWAP( p_bordel[ 6 ], p_bordel[ 7 ] );
1459 SWAP( p_bordel[ 13 ], p_bordel[ 14 ] );
1462 p_bordel[ i ] += p_bordel[ 1 ] ^ 0x80080011;
1463 p_bordel[ i ] += p_bordel[ 2 ] ^ 0xBEEFDEAD;
1464 p_bordel[ i ] += p_bordel[ 3 ] ^ 0x8765F444;
1465 p_bordel[ i ] += p_bordel[ 4 ] ^ 0x78145326;
1468 p_bordel[ 12 ] -= p_bordel[ i ];
1469 p_bordel[ 13 ] += p_bordel[ i ];
1472 p_bordel[ i ] += p_bordel[ 1 ];
1473 p_bordel[ i ] -= p_bordel[ 7 ];
1474 p_bordel[ i ] -= p_bordel[ 8 ];
1475 p_bordel[ i ] += p_bordel[ 9 ];
1476 p_bordel[ i ] += p_bordel[ 13 ];
1480 p_bordel[ i + 1 ] >>= 1;
1481 p_bordel[ i + 2 ] <<= 4;
1482 p_bordel[ i + 3 ] >>= 3;
1485 p_bordel[ 1 ] += 0x20E;
1486 p_bordel[ 5 ] += 0x223D;
1487 p_bordel[ 13 ] -= 0x576;
1488 p_bordel[ 15 ] += 0x576;
1491 if( (p_bordel[ i ] ^ 0x8765F441) < 0x2710 )
1493 SWAP( p_bordel[ 0 ], p_bordel[ 1 ] );
1497 SWAP( p_bordel[ 1 ], p_bordel[ 11 ] );
1503 /*****************************************************************************
1504 * GetSystemKey: get the system key
1505 *****************************************************************************
1506 * Compute the system key from various system information, see HashSystemInfo.
1507 *****************************************************************************/
1508 static int GetSystemKey( uint32_t *p_sys_key, vlc_bool_t b_ipod )
1510 static char const p_secret5[ 8 ] = "YuaFlafu";
1511 static char const p_secret6[ 8 ] = "zPif98ga";
1514 uint32_t p_system_hash[ 4 ];
1516 /* Compute the MD5 hash of our system info */
1517 if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) ||
1518 ( b_ipod && GetiPodID( &i_ipod_id ) ) )
1523 /* Combine our system info hash with additional secret data. The resulting
1524 * MD5 hash will be our system key. */
1526 AddMD5( &md5, (const uint8_t*)p_secret5, 8 );
1530 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1531 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1532 AddMD5( &md5, (const uint8_t *)p_system_hash, 6 );
1533 AddMD5( &md5, (const uint8_t *)p_secret6, 8 );
1537 i_ipod_id = U64_AT(&i_ipod_id);
1538 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1539 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1540 AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
1545 memcpy( p_sys_key, md5.p_digest, 16 );
1551 # define DRMS_DIRNAME "drms"
1553 # define DRMS_DIRNAME ".drms"
1556 /*****************************************************************************
1557 * WriteUserKey: write the user key to hard disk
1558 *****************************************************************************
1559 * Write the user key to the hard disk so that it can be reused later or used
1560 * on operating systems other than Win32.
1561 *****************************************************************************/
1562 static int WriteUserKey( void *_p_drms, uint32_t *p_user_key )
1564 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1567 char psz_path[ PATH_MAX ];
1569 snprintf( psz_path, PATH_MAX - 1,
1570 "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
1572 #if defined( HAVE_ERRNO_H )
1573 # if defined( WIN32 )
1574 if( !mkdir( psz_path ) || errno == EEXIST )
1576 if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
1579 if( !mkdir( psz_path ) )
1582 snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d",
1583 p_drms->psz_homedir, p_drms->i_user, p_drms->i_key );
1585 file = utf8_fopen( psz_path, "wb" );
1588 i_ret = fwrite( p_user_key, sizeof(uint32_t),
1589 4, file ) == 4 ? 0 : -1;
1597 /*****************************************************************************
1598 * ReadUserKey: read the user key from hard disk
1599 *****************************************************************************
1600 * Retrieve the user key from the hard disk if available.
1601 *****************************************************************************/
1602 static int ReadUserKey( void *_p_drms, uint32_t *p_user_key )
1604 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1607 char psz_path[ PATH_MAX ];
1609 snprintf( psz_path, PATH_MAX - 1,
1610 "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir,
1611 p_drms->i_user, p_drms->i_key );
1613 file = utf8_fopen( psz_path, "rb" );
1616 i_ret = fread( p_user_key, sizeof(uint32_t),
1617 4, file ) == 4 ? 0 : -1;
1624 /*****************************************************************************
1625 * GetUserKey: get the user key
1626 *****************************************************************************
1627 * Retrieve the user key from the hard disk if available, otherwise generate
1628 * it from the system key. If the key could be successfully generated, write
1629 * it to the hard disk for future use.
1630 *****************************************************************************/
1631 static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
1633 static char const p_secret7[] = "mUfnpognadfgf873";
1634 struct drms_s *p_drms = (struct drms_s *)_p_drms;
1636 struct shuffle_s shuffle;
1638 uint32_t *p_sci_data = NULL;
1639 uint32_t i_user, i_key;
1640 uint32_t p_sys_key[ 4 ];
1641 uint32_t i_sci_size = 0, i_blocks, i_remaining;
1642 uint32_t *p_sci0, *p_sci1, *p_buffer;
1643 uint32_t p_sci_key[ 4 ];
1647 if( ReadUserKey( p_drms, p_user_key ) == 0 )
1649 REVERSE( p_user_key, 4 );
1653 psz_ipod = getenv( "IPOD" );
1655 if( GetSystemKey( p_sys_key, psz_ipod ? VLC_TRUE : VLC_FALSE ) )
1660 if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
1665 /* Phase 1: unscramble the SCI data using the system key and shuffle
1666 * it using DoShuffle(). */
1668 /* Skip the first 4 bytes (some sort of header). Decrypt the rest. */
1669 i_blocks = (i_sci_size - 4) / 16;
1670 i_remaining = (i_sci_size - 4) - (i_blocks * 16);
1671 p_buffer = p_sci_data + 1;
1673 /* Decrypt and shuffle our data at the same time */
1674 InitAES( &aes, p_sys_key );
1675 REVERSE( p_sys_key, 4 );
1676 REVERSE( p_sci_data, 1 );
1677 InitShuffle( &shuffle, p_sys_key, p_sci_data[ 0 ] );
1679 memcpy( p_sci_key, p_secret7, 16 );
1680 REVERSE( p_sci_key, 4 );
1684 uint32_t p_tmp[ 4 ];
1686 REVERSE( p_buffer, 4 );
1687 DecryptAES( &aes, p_tmp, p_buffer );
1688 BlockXOR( p_tmp, p_sci_key, p_tmp );
1690 /* Use the previous scrambled data as the key for next block */
1691 memcpy( p_sci_key, p_buffer, 16 );
1693 /* Shuffle the decrypted data using a custom routine */
1694 DoShuffle( &shuffle, p_tmp, 4 );
1696 /* Copy this block back to p_buffer */
1697 memcpy( p_buffer, p_tmp, 16 );
1702 if( i_remaining >= 4 )
1704 REVERSE( p_buffer, i_remaining / 4 );
1705 DoShuffle( &shuffle, p_buffer, i_remaining / 4 );
1708 /* Phase 2: look for the user key in the generated data. I must admit I
1709 * do not understand what is going on here, because it almost
1710 * looks like we are browsing data that makes sense, even though
1711 * the DoShuffle() part made it completely meaningless. */
1714 REVERSE( p_sci_data + 5, 1 );
1715 i = U32_AT( p_sci_data + 5 );
1716 i_sci_size -= 22 * sizeof(uint32_t);
1717 p_sci1 = p_sci_data + 22;
1720 while( i_sci_size >= 20 && i > 0 )
1722 if( p_sci0 == NULL )
1724 i_sci_size -= 18 * sizeof(uint32_t);
1725 if( i_sci_size < 20 )
1731 REVERSE( p_sci1 + 17, 1 );
1732 y = U32_AT( p_sci1 + 17 );
1743 i_user = U32_AT( p_sci0 );
1744 i_key = U32_AT( p_sci1 );
1745 REVERSE( &i_user, 1 );
1746 REVERSE( &i_key, 1 );
1747 if( i_user == p_drms->i_user && ( ( i_key == p_drms->i_key ) ||
1748 ( !p_drms->i_key && ( p_sci1 == (p_sci0 + 18) ) ) ) )
1750 memcpy( p_user_key, p_sci1 + 1, 16 );
1751 REVERSE( p_sci1 + 1, 4 );
1752 WriteUserKey( p_drms, p_sci1 + 1 );
1759 i_sci_size -= 5 * sizeof(uint32_t);
1767 /*****************************************************************************
1768 * GetSCIData: get SCI data from "SC Info.sidb"
1769 *****************************************************************************
1770 * Read SCI data from "\Apple Computer\iTunes\SC Info\SC Info.sidb"
1771 *****************************************************************************/
1772 static int GetSCIData( char *psz_ipod, uint32_t **pp_sci,
1773 uint32_t *pi_sci_size )
1776 char *psz_path = NULL;
1777 char p_tmp[ 4 * PATH_MAX ];
1780 if( psz_ipod == NULL )
1783 const wchar_t *wfile =
1784 L"\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb";
1785 typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
1787 HINSTANCE shfolder_dll = NULL;
1788 SHGETFOLDERPATH dSHGetFolderPath = NULL;
1789 wchar_t wpath[PATH_MAX];
1791 if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
1794 (SHGETFOLDERPATH)GetProcAddress( shfolder_dll,
1795 _T("SHGetFolderPathW") );
1798 if( dSHGetFolderPath != NULL &&
1799 SUCCEEDED( dSHGetFolderPath( NULL, CSIDL_COMMON_APPDATA,
1800 NULL, 0, wpath ) ) )
1802 if (wcslen( wpath ) + wcslen( wfile ) >= PATH_MAX )
1806 wcscat( wpath, wfile );
1808 psz_path = FromWide( wpath );
1809 strncpy( p_tmp, psz_path, sizeof( p_tmp ) - 1 );
1810 p_tmp[sizeof( p_tmp ) - 1] = '\0';
1815 if( shfolder_dll != NULL )
1817 FreeLibrary( shfolder_dll );
1823 #define ISCINFO "iSCInfo"
1824 if( strstr( psz_ipod, ISCINFO ) == NULL )
1826 snprintf( p_tmp, sizeof(p_tmp) - 1,
1827 "%s/iPod_Control/iTunes/" ISCINFO "2", psz_ipod );
1832 psz_path = psz_ipod;
1836 if( psz_path == NULL )
1841 file = utf8_fopen( psz_path, "rb" );
1846 if( !fstat( fileno( file ), &st ) && st.st_size >= 4 )
1848 *pp_sci = malloc( st.st_size );
1849 if( *pp_sci != NULL )
1851 if( fread( *pp_sci, 1, st.st_size,
1852 file ) == (size_t)st.st_size )
1854 *pi_sci_size = st.st_size;
1859 free( (void *)*pp_sci );
1871 /*****************************************************************************
1872 * HashSystemInfo: hash system information
1873 *****************************************************************************
1874 * This function computes the MD5 hash of the C: hard drive serial number,
1875 * BIOS version, CPU type and Windows version.
1876 *****************************************************************************/
1877 static int HashSystemInfo( uint32_t *p_system_hash )
1889 static LPCTSTR p_reg_keys[ 3 ][ 2 ] =
1892 _T("HARDWARE\\DESCRIPTION\\System"),
1893 _T("SystemBiosVersion")
1897 _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
1898 _T("ProcessorNameString")
1902 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
1909 AddMD5( &md5, "cache-control", 13 );
1910 AddMD5( &md5, "Ethernet", 8 );
1912 GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
1913 NULL, NULL, NULL, 0 );
1914 AddMD5( &md5, (const uint8_t *)&i_serial, 4 );
1916 for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
1918 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
1919 0, KEY_READ, &i_key ) != ERROR_SUCCESS )
1924 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1925 NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
1927 RegCloseKey( i_key );
1931 p_reg_buf = malloc( i_size );
1933 if( p_reg_buf != NULL )
1935 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1936 NULL, NULL, p_reg_buf,
1937 &i_size ) == ERROR_SUCCESS )
1939 AddMD5( &md5, (const uint8_t *)p_reg_buf, i_size );
1945 RegCloseKey( i_key );
1954 memcpy( p_system_hash, md5.p_digest, 16 );
1959 /*****************************************************************************
1960 * GetiPodID: Get iPod ID
1961 *****************************************************************************
1962 * This function gets the iPod ID.
1963 *****************************************************************************/
1964 static int GetiPodID( int64_t *p_ipod_id )
1968 #define PROD_NAME "iPod"
1969 #define VENDOR_NAME "Apple Computer, Inc."
1971 char *psz_ipod_id = getenv( "IPODID" );
1972 if( psz_ipod_id != NULL )
1974 *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
1982 io_iterator_t iterator;
1983 CFMutableDictionaryRef match_dic;
1984 CFMutableDictionaryRef smatch_dic;
1986 if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
1988 smatch_dic = IOServiceMatching( "IOFireWireUnit" );
1989 match_dic = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
1990 &kCFTypeDictionaryKeyCallBacks,
1991 &kCFTypeDictionaryValueCallBacks );
1993 if( smatch_dic != NULL && match_dic != NULL )
1995 CFDictionarySetValue( smatch_dic,
1996 CFSTR("FireWire Vendor Name"),
1997 CFSTR(VENDOR_NAME) );
1998 CFDictionarySetValue( smatch_dic,
1999 CFSTR("FireWire Product Name"),
2002 CFDictionarySetValue( match_dic,
2003 CFSTR(kIOPropertyMatchKey),
2006 if( IOServiceGetMatchingServices( port, match_dic,
2007 &iterator ) == KERN_SUCCESS )
2009 while( ( device = IOIteratorNext( iterator ) ) != NULL )
2011 value = IORegistryEntryCreateCFProperty( device,
2012 CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );
2016 if( CFGetTypeID( value ) == CFNumberGetTypeID() )
2019 CFNumberGetValue( (CFNumberRef)value,
2020 kCFNumberLongLongType,
2022 *p_ipod_id = i_ipod_id;
2029 IOObjectRelease( device );
2034 IOObjectRelease( iterator );
2038 mach_port_deallocate( mach_task_self(), port );
2041 #elif defined (HAVE_SYSFS_LIBSYSFS_H)
2042 struct sysfs_bus *bus = NULL;
2043 struct dlist *devlist = NULL;
2044 struct dlist *attributes = NULL;
2045 struct sysfs_device *curdev = NULL;
2046 struct sysfs_attribute *curattr = NULL;
2048 bus = sysfs_open_bus( "ieee1394" );
2051 devlist = sysfs_get_bus_devices( bus );
2052 if( devlist != NULL )
2054 dlist_for_each_data( devlist, curdev, struct sysfs_device )
2056 attributes = sysfs_get_device_attributes( curdev );
2057 if( attributes != NULL )
2059 dlist_for_each_data( attributes, curattr,
2060 struct sysfs_attribute )
2062 if( ( strcmp( curattr->name, "model_name" ) == 0 ) &&
2063 ( strncmp( curattr->value, PROD_NAME,
2064 sizeof(PROD_NAME) ) == 0 ) )
2066 *p_ipod_id = strtoll( curdev->name, NULL, 16 );
2077 sysfs_close_bus( bus );
2084 #else /* !defined( UNDER_CE ) */
2086 void *drms_alloc( char *psz_homedir ){ return 0; }
2087 void drms_free( void *a ){}
2088 void drms_decrypt( void *a, uint32_t *b, uint32_t c ){}
2089 int drms_init( void *a, uint32_t b, uint8_t *c, uint32_t d ){ return -1; }
2091 #endif /* defined( UNDER_CE ) */