00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stdlib.h>
00026
00027 #ifdef WIN32
00028 # include <io.h>
00029 #else
00030 # include <stdio.h>
00031 #endif
00032
00033 #ifdef __VLC__
00034 # include <vlc/vlc.h>
00035 # include <vlc_md5.h>
00036 # include "libmp4.h"
00037 #else
00038 # include "drmsvl.h"
00039 #endif
00040
00041 #ifdef HAVE_ERRNO_H
00042 # include <errno.h>
00043 #endif
00044
00045 #ifdef WIN32
00046 # if !defined( UNDER_CE )
00047 # include <direct.h>
00048 # endif
00049 # include <tchar.h>
00050 # include <shlobj.h>
00051 # include <windows.h>
00052 #endif
00053
00054 #ifdef HAVE_SYS_STAT_H
00055 # include <sys/stat.h>
00056 #endif
00057 #ifdef HAVE_SYS_TYPES_H
00058 # include <sys/types.h>
00059 #endif
00060
00061
00062 #ifdef HAVE_LIMITS_H
00063 # include <limits.h>
00064 #endif
00065
00066 #ifdef SYS_DARWIN
00067 # include <mach/mach.h>
00068 # include <IOKit/IOKitLib.h>
00069 # include <CoreFoundation/CFNumber.h>
00070 #endif
00071
00072 #ifdef HAVE_SYSFS_LIBSYSFS_H
00073 # include <sysfs/libsysfs.h>
00074 #endif
00075
00076 #include "drms.h"
00077 #include "drmstables.h"
00078
00079 #if !defined( UNDER_CE )
00080
00081
00082
00083
00084
00085
00086 struct aes_s
00087 {
00088 uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
00089 uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
00090 };
00091
00092 #ifdef __VLC__
00093 # define Digest DigestMD5
00094 #else
00095
00096
00097
00098
00099
00100
00101 struct md5_s
00102 {
00103 uint64_t i_bits;
00104 uint32_t p_digest[4];
00105 uint32_t p_data[16];
00106 };
00107 #endif
00108
00109
00110
00111
00112
00113
00114
00115 struct shuffle_s
00116 {
00117 uint32_t i_version;
00118 uint32_t p_commands[ 20 ];
00119 uint32_t p_bordel[ 16 ];
00120 };
00121
00122 #define SWAP( a, b ) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
00123
00124
00125
00126
00127
00128
00129 struct drms_s
00130 {
00131 uint32_t i_user;
00132 uint32_t i_key;
00133 uint8_t p_iviv[ 16 ];
00134 uint8_t *p_name;
00135
00136 uint32_t p_key[ 4 ];
00137 struct aes_s aes;
00138
00139 char psz_homedir[ PATH_MAX ];
00140 };
00141
00142
00143
00144
00145 static void InitAES ( struct aes_s *, uint32_t * );
00146 static void DecryptAES ( struct aes_s *, uint32_t *, const uint32_t * );
00147
00148 #ifndef __VLC__
00149 static void InitMD5 ( struct md5_s * );
00150 static void AddMD5 ( struct md5_s *, const uint8_t *, uint32_t );
00151 static void EndMD5 ( struct md5_s * );
00152 static void Digest ( struct md5_s *, uint32_t * );
00153 #endif
00154
00155 static void InitShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
00156 static void DoShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
00157
00158 static uint32_t FirstPass ( uint32_t * );
00159 static void SecondPass ( uint32_t *, uint32_t );
00160 static void ThirdPass ( uint32_t * );
00161 static void FourthPass ( uint32_t * );
00162 static void TinyShuffle1 ( uint32_t * );
00163 static void TinyShuffle2 ( uint32_t * );
00164 static void TinyShuffle3 ( uint32_t * );
00165 static void TinyShuffle4 ( uint32_t * );
00166 static void TinyShuffle5 ( uint32_t * );
00167 static void TinyShuffle6 ( uint32_t * );
00168 static void TinyShuffle7 ( uint32_t * );
00169 static void TinyShuffle8 ( uint32_t * );
00170 static void DoExtShuffle ( uint32_t * );
00171
00172 static int GetSystemKey ( uint32_t *, vlc_bool_t );
00173 static int WriteUserKey ( void *, uint32_t * );
00174 static int ReadUserKey ( void *, uint32_t * );
00175 static int GetUserKey ( void *, uint32_t * );
00176
00177 static int GetSCIData ( char *, uint32_t **, uint32_t * );
00178 static int HashSystemInfo ( uint32_t * );
00179 static int GetiPodID ( int64_t * );
00180
00181 #ifdef WORDS_BIGENDIAN
00182
00183
00184
00185 static inline void Reverse( uint32_t *p_buffer, int n )
00186 {
00187 int i;
00188
00189 for( i = 0; i < n; i++ )
00190 {
00191 p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
00192 }
00193 }
00194 # define REVERSE( p, n ) Reverse( p, n )
00195 #else
00196 # define REVERSE( p, n )
00197 #endif
00198
00199
00200
00201
00202 static inline void BlockXOR( uint32_t *p_dest, uint32_t *p_s1, uint32_t *p_s2 )
00203 {
00204 int i;
00205
00206 for( i = 0; i < 4; i++ )
00207 {
00208 p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
00209 }
00210 }
00211
00212
00213
00214
00215 void *drms_alloc( char *psz_homedir )
00216 {
00217 struct drms_s *p_drms;
00218
00219 p_drms = malloc( sizeof(struct drms_s) );
00220
00221 if( p_drms == NULL )
00222 {
00223 return NULL;
00224 }
00225
00226 memset( p_drms, 0, sizeof(struct drms_s) );
00227
00228 strncpy( p_drms->psz_homedir, psz_homedir, PATH_MAX );
00229 p_drms->psz_homedir[ PATH_MAX - 1 ] = '\0';
00230
00231 return (void *)p_drms;
00232 }
00233
00234
00235
00236
00237 void drms_free( void *_p_drms )
00238 {
00239 struct drms_s *p_drms = (struct drms_s *)_p_drms;
00240
00241 if( p_drms->p_name != NULL )
00242 {
00243 free( (void *)p_drms->p_name );
00244 }
00245
00246 free( p_drms );
00247 }
00248
00249
00250
00251
00252 void drms_decrypt( void *_p_drms, uint32_t *p_buffer, uint32_t i_bytes )
00253 {
00254 struct drms_s *p_drms = (struct drms_s *)_p_drms;
00255 uint32_t p_key[ 4 ];
00256 unsigned int i_blocks;
00257
00258
00259 i_blocks = i_bytes / 16;
00260 i_bytes = i_blocks * 16;
00261
00262
00263 memcpy( p_key, p_drms->p_key, 16 );
00264
00265
00266 while( i_blocks-- )
00267 {
00268 uint32_t p_tmp[ 4 ];
00269
00270 REVERSE( p_buffer, 4 );
00271 DecryptAES( &p_drms->aes, p_tmp, p_buffer );
00272 BlockXOR( p_tmp, p_key, p_tmp );
00273
00274
00275 memcpy( p_key, p_buffer, 16 );
00276
00277
00278 memcpy( p_buffer, p_tmp, 16 );
00279 REVERSE( p_buffer, 4 );
00280
00281 p_buffer += 4;
00282 }
00283 }
00284
00285
00286
00287
00288 int drms_init( void *_p_drms, uint32_t i_type,
00289 uint8_t *p_info, uint32_t i_len )
00290 {
00291 struct drms_s *p_drms = (struct drms_s *)_p_drms;
00292 int i_ret = 0;
00293
00294 switch( i_type )
00295 {
00296 case FOURCC_user:
00297 if( i_len < sizeof(p_drms->i_user) )
00298 {
00299 i_ret = -1;
00300 break;
00301 }
00302
00303 p_drms->i_user = U32_AT( p_info );
00304 break;
00305
00306 case FOURCC_key:
00307 if( i_len < sizeof(p_drms->i_key) )
00308 {
00309 i_ret = -1;
00310 break;
00311 }
00312
00313 p_drms->i_key = U32_AT( p_info );
00314 break;
00315
00316 case FOURCC_iviv:
00317 if( i_len < sizeof(p_drms->p_key) )
00318 {
00319 i_ret = -1;
00320 break;
00321 }
00322
00323 memcpy( p_drms->p_iviv, p_info, 16 );
00324 break;
00325
00326 case FOURCC_name:
00327 p_drms->p_name = strdup( p_info );
00328
00329 if( p_drms->p_name == NULL )
00330 {
00331 i_ret = -1;
00332 }
00333 break;
00334
00335 case FOURCC_priv:
00336 {
00337 uint32_t p_priv[ 64 ];
00338 struct md5_s md5;
00339
00340 if( i_len < 64 )
00341 {
00342 i_ret = -1;
00343 break;
00344 }
00345
00346 InitMD5( &md5 );
00347 AddMD5( &md5, p_drms->p_name, strlen( p_drms->p_name ) );
00348 AddMD5( &md5, p_drms->p_iviv, 16 );
00349 EndMD5( &md5 );
00350
00351 if( p_drms->i_user == 0 && p_drms->i_key == 0 )
00352 {
00353 static char const p_secret[] = "tr1-th3n.y00_by3";
00354 memcpy( p_drms->p_key, p_secret, 16 );
00355 REVERSE( p_drms->p_key, 4 );
00356 }
00357 else
00358 {
00359 if( GetUserKey( p_drms, p_drms->p_key ) )
00360 {
00361 i_ret = -1;
00362 break;
00363 }
00364 }
00365
00366 InitAES( &p_drms->aes, p_drms->p_key );
00367
00368 memcpy( p_priv, p_info, 64 );
00369 memcpy( p_drms->p_key, md5.p_digest, 16 );
00370 drms_decrypt( p_drms, p_priv, 64 );
00371 REVERSE( p_priv, 64 );
00372
00373 if( p_priv[ 0 ] != 0x6e757469 )
00374 {
00375 i_ret = -1;
00376 break;
00377 }
00378
00379 InitAES( &p_drms->aes, p_priv + 6 );
00380 memcpy( p_drms->p_key, p_priv + 12, 16 );
00381
00382 free( (void *)p_drms->p_name );
00383 p_drms->p_name = NULL;
00384 }
00385 break;
00386 }
00387
00388 return i_ret;
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398 static void InitAES( struct aes_s *p_aes, uint32_t *p_key )
00399 {
00400 unsigned int i, t;
00401 uint32_t i_key, i_seed;
00402
00403 memset( p_aes->pp_enc_keys[1], 0, 16 );
00404 memcpy( p_aes->pp_enc_keys[0], p_key, 16 );
00405
00406
00407 i_seed = p_aes->pp_enc_keys[ 0 ][ 3 ];
00408
00409 for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
00410 {
00411 uint32_t j;
00412
00413 i_seed = AES_ROR( i_seed, 8 );
00414
00415 j = p_aes_table[ i_key ];
00416
00417 j ^= p_aes_encrypt[ (i_seed >> 24) & 0xff ]
00418 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 16) & 0xff ], 8 )
00419 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 8) & 0xff ], 16 )
00420 ^ AES_ROR( p_aes_encrypt[ i_seed & 0xff ], 24 );
00421
00422 j ^= p_aes->pp_enc_keys[ i_key ][ 0 ];
00423 p_aes->pp_enc_keys[ i_key + 1 ][ 0 ] = j;
00424 j ^= p_aes->pp_enc_keys[ i_key ][ 1 ];
00425 p_aes->pp_enc_keys[ i_key + 1 ][ 1 ] = j;
00426 j ^= p_aes->pp_enc_keys[ i_key ][ 2 ];
00427 p_aes->pp_enc_keys[ i_key + 1 ][ 2 ] = j;
00428 j ^= p_aes->pp_enc_keys[ i_key ][ 3 ];
00429 p_aes->pp_enc_keys[ i_key + 1 ][ 3 ] = j;
00430
00431 i_seed = j;
00432 }
00433
00434 memcpy( p_aes->pp_dec_keys[ 0 ],
00435 p_aes->pp_enc_keys[ 0 ], 16 );
00436
00437 for( i = 1; i < AES_KEY_COUNT; i++ )
00438 {
00439 for( t = 0; t < 4; t++ )
00440 {
00441 uint32_t j, k, l, m, n;
00442
00443 j = p_aes->pp_enc_keys[ i ][ t ];
00444
00445 k = (((j >> 7) & 0x01010101) * 27) ^ ((j & 0xff7f7f7f) << 1);
00446 l = (((k >> 7) & 0x01010101) * 27) ^ ((k & 0xff7f7f7f) << 1);
00447 m = (((l >> 7) & 0x01010101) * 27) ^ ((l & 0xff7f7f7f) << 1);
00448
00449 j ^= m;
00450
00451 n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
00452
00453 p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
00454 }
00455 }
00456 }
00457
00458
00459
00460
00461 static void DecryptAES( struct aes_s *p_aes,
00462 uint32_t *p_dest, const uint32_t *p_src )
00463 {
00464 uint32_t p_wtxt[ 4 ];
00465 uint32_t p_tmp[ 4 ];
00466 unsigned int i_round, t;
00467
00468 for( t = 0; t < 4; t++ )
00469 {
00470
00471 p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
00472 }
00473
00474
00475 for( i_round = 0; i_round < (AES_KEY_COUNT - 1); i_round++ )
00476 {
00477 for( t = 0; t < 4; t++ )
00478 {
00479 p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
00480 }
00481
00482 for( t = 0; t < 4; t++ )
00483 {
00484 p_wtxt[ t ] = p_tmp[ t ]
00485 ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - i_round ][ t ];
00486 }
00487 }
00488
00489
00490 for( t = 0; t < 4; t++ )
00491 {
00492 p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
00493 p_dest[ t ] ^= p_aes->pp_dec_keys[ 0 ][ t ];
00494 }
00495 }
00496
00497 #ifndef __VLC__
00498
00499
00500
00501
00502
00503 static void InitMD5( struct md5_s *p_md5 )
00504 {
00505 p_md5->p_digest[ 0 ] = 0x67452301;
00506 p_md5->p_digest[ 1 ] = 0xefcdab89;
00507 p_md5->p_digest[ 2 ] = 0x98badcfe;
00508 p_md5->p_digest[ 3 ] = 0x10325476;
00509
00510 memset( p_md5->p_data, 0, 64 );
00511 p_md5->i_bits = 0;
00512 }
00513
00514
00515
00516
00517 static void AddMD5( struct md5_s *p_md5, const uint8_t *p_src, uint32_t i_len )
00518 {
00519 unsigned int i_current;
00520 unsigned int i_offset = 0;
00521
00522 i_current = (p_md5->i_bits / 8) & 63;
00523
00524 p_md5->i_bits += 8 * i_len;
00525
00526
00527
00528 if( i_len >= (64 - i_current) )
00529 {
00530 memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src,
00531 (64 - i_current) );
00532 Digest( p_md5, p_md5->p_data );
00533
00534 i_offset += (64 - i_current);
00535 i_len -= (64 - i_current);
00536 i_current = 0;
00537 }
00538
00539
00540 while( i_len >= 64 )
00541 {
00542 uint32_t p_tmp[ 16 ];
00543 memcpy( p_tmp, p_src + i_offset, 64 );
00544 Digest( p_md5, p_tmp );
00545 i_offset += 64;
00546 i_len -= 64;
00547 }
00548
00549
00550 memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src + i_offset, i_len );
00551 }
00552
00553
00554
00555
00556
00557
00558
00559 static void EndMD5( struct md5_s *p_md5 )
00560 {
00561 unsigned int i_current;
00562
00563 i_current = (p_md5->i_bits / 8) & 63;
00564
00565
00566
00567 ((uint8_t *)p_md5->p_data)[ i_current++ ] = 0x80;
00568
00569
00570
00571
00572 if( i_current > 56 )
00573 {
00574 memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (64 - i_current) );
00575 Digest( p_md5, p_md5->p_data );
00576 i_current = 0;
00577 }
00578
00579
00580
00581 memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (56 - i_current) );
00582 p_md5->p_data[ 14 ] = p_md5->i_bits & 0xffffffff;
00583 p_md5->p_data[ 15 ] = (p_md5->i_bits >> 32);
00584 REVERSE( &p_md5->p_data[ 14 ], 2 );
00585
00586 Digest( p_md5, p_md5->p_data );
00587 }
00588
00589 #define F1( x, y, z ) ((z) ^ ((x) & ((y) ^ (z))))
00590 #define F2( x, y, z ) F1((z), (x), (y))
00591 #define F3( x, y, z ) ((x) ^ (y) ^ (z))
00592 #define F4( x, y, z ) ((y) ^ ((x) | ~(z)))
00593
00594 #define MD5_DO( f, w, x, y, z, data, s ) \
00595 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
00596
00597
00598
00599
00600 static void Digest( struct md5_s *p_md5, uint32_t *p_input )
00601 {
00602 uint32_t a, b, c, d;
00603
00604 REVERSE( p_input, 16 );
00605
00606 a = p_md5->p_digest[ 0 ];
00607 b = p_md5->p_digest[ 1 ];
00608 c = p_md5->p_digest[ 2 ];
00609 d = p_md5->p_digest[ 3 ];
00610
00611 MD5_DO( F1, a, b, c, d, p_input[ 0 ] + 0xd76aa478, 7 );
00612 MD5_DO( F1, d, a, b, c, p_input[ 1 ] + 0xe8c7b756, 12 );
00613 MD5_DO( F1, c, d, a, b, p_input[ 2 ] + 0x242070db, 17 );
00614 MD5_DO( F1, b, c, d, a, p_input[ 3 ] + 0xc1bdceee, 22 );
00615 MD5_DO( F1, a, b, c, d, p_input[ 4 ] + 0xf57c0faf, 7 );
00616 MD5_DO( F1, d, a, b, c, p_input[ 5 ] + 0x4787c62a, 12 );
00617 MD5_DO( F1, c, d, a, b, p_input[ 6 ] + 0xa8304613, 17 );
00618 MD5_DO( F1, b, c, d, a, p_input[ 7 ] + 0xfd469501, 22 );
00619 MD5_DO( F1, a, b, c, d, p_input[ 8 ] + 0x698098d8, 7 );
00620 MD5_DO( F1, d, a, b, c, p_input[ 9 ] + 0x8b44f7af, 12 );
00621 MD5_DO( F1, c, d, a, b, p_input[ 10 ] + 0xffff5bb1, 17 );
00622 MD5_DO( F1, b, c, d, a, p_input[ 11 ] + 0x895cd7be, 22 );
00623 MD5_DO( F1, a, b, c, d, p_input[ 12 ] + 0x6b901122, 7 );
00624 MD5_DO( F1, d, a, b, c, p_input[ 13 ] + 0xfd987193, 12 );
00625 MD5_DO( F1, c, d, a, b, p_input[ 14 ] + 0xa679438e, 17 );
00626 MD5_DO( F1, b, c, d, a, p_input[ 15 ] + 0x49b40821, 22 );
00627
00628 MD5_DO( F2, a, b, c, d, p_input[ 1 ] + 0xf61e2562, 5 );
00629 MD5_DO( F2, d, a, b, c, p_input[ 6 ] + 0xc040b340, 9 );
00630 MD5_DO( F2, c, d, a, b, p_input[ 11 ] + 0x265e5a51, 14 );
00631 MD5_DO( F2, b, c, d, a, p_input[ 0 ] + 0xe9b6c7aa, 20 );
00632 MD5_DO( F2, a, b, c, d, p_input[ 5 ] + 0xd62f105d, 5 );
00633 MD5_DO( F2, d, a, b, c, p_input[ 10 ] + 0x02441453, 9 );
00634 MD5_DO( F2, c, d, a, b, p_input[ 15 ] + 0xd8a1e681, 14 );
00635 MD5_DO( F2, b, c, d, a, p_input[ 4 ] + 0xe7d3fbc8, 20 );
00636 MD5_DO( F2, a, b, c, d, p_input[ 9 ] + 0x21e1cde6, 5 );
00637 MD5_DO( F2, d, a, b, c, p_input[ 14 ] + 0xc33707d6, 9 );
00638 MD5_DO( F2, c, d, a, b, p_input[ 3 ] + 0xf4d50d87, 14 );
00639 MD5_DO( F2, b, c, d, a, p_input[ 8 ] + 0x455a14ed, 20 );
00640 MD5_DO( F2, a, b, c, d, p_input[ 13 ] + 0xa9e3e905, 5 );
00641 MD5_DO( F2, d, a, b, c, p_input[ 2 ] + 0xfcefa3f8, 9 );
00642 MD5_DO( F2, c, d, a, b, p_input[ 7 ] + 0x676f02d9, 14 );
00643 MD5_DO( F2, b, c, d, a, p_input[ 12 ] + 0x8d2a4c8a, 20 );
00644
00645 MD5_DO( F3, a, b, c, d, p_input[ 5 ] + 0xfffa3942, 4 );
00646 MD5_DO( F3, d, a, b, c, p_input[ 8 ] + 0x8771f681, 11 );
00647 MD5_DO( F3, c, d, a, b, p_input[ 11 ] + 0x6d9d6122, 16 );
00648 MD5_DO( F3, b, c, d, a, p_input[ 14 ] + 0xfde5380c, 23 );
00649 MD5_DO( F3, a, b, c, d, p_input[ 1 ] + 0xa4beea44, 4 );
00650 MD5_DO( F3, d, a, b, c, p_input[ 4 ] + 0x4bdecfa9, 11 );
00651 MD5_DO( F3, c, d, a, b, p_input[ 7 ] + 0xf6bb4b60, 16 );
00652 MD5_DO( F3, b, c, d, a, p_input[ 10 ] + 0xbebfbc70, 23 );
00653 MD5_DO( F3, a, b, c, d, p_input[ 13 ] + 0x289b7ec6, 4 );
00654 MD5_DO( F3, d, a, b, c, p_input[ 0 ] + 0xeaa127fa, 11 );
00655 MD5_DO( F3, c, d, a, b, p_input[ 3 ] + 0xd4ef3085, 16 );
00656 MD5_DO( F3, b, c, d, a, p_input[ 6 ] + 0x04881d05, 23 );
00657 MD5_DO( F3, a, b, c, d, p_input[ 9 ] + 0xd9d4d039, 4 );
00658 MD5_DO( F3, d, a, b, c, p_input[ 12 ] + 0xe6db99e5, 11 );
00659 MD5_DO( F3, c, d, a, b, p_input[ 15 ] + 0x1fa27cf8, 16 );
00660 MD5_DO( F3, b, c, d, a, p_input[ 2 ] + 0xc4ac5665, 23 );
00661
00662 MD5_DO( F4, a, b, c, d, p_input[ 0 ] + 0xf4292244, 6 );
00663 MD5_DO( F4, d, a, b, c, p_input[ 7 ] + 0x432aff97, 10 );
00664 MD5_DO( F4, c, d, a, b, p_input[ 14 ] + 0xab9423a7, 15 );
00665 MD5_DO( F4, b, c, d, a, p_input[ 5 ] + 0xfc93a039, 21 );
00666 MD5_DO( F4, a, b, c, d, p_input[ 12 ] + 0x655b59c3, 6 );
00667 MD5_DO( F4, d, a, b, c, p_input[ 3 ] + 0x8f0ccc92, 10 );
00668 MD5_DO( F4, c, d, a, b, p_input[ 10 ] + 0xffeff47d, 15 );
00669 MD5_DO( F4, b, c, d, a, p_input[ 1 ] + 0x85845dd1, 21 );
00670 MD5_DO( F4, a, b, c, d, p_input[ 8 ] + 0x6fa87e4f, 6 );
00671 MD5_DO( F4, d, a, b, c, p_input[ 15 ] + 0xfe2ce6e0, 10 );
00672 MD5_DO( F4, c, d, a, b, p_input[ 6 ] + 0xa3014314, 15 );
00673 MD5_DO( F4, b, c, d, a, p_input[ 13 ] + 0x4e0811a1, 21 );
00674 MD5_DO( F4, a, b, c, d, p_input[ 4 ] + 0xf7537e82, 6 );
00675 MD5_DO( F4, d, a, b, c, p_input[ 11 ] + 0xbd3af235, 10 );
00676 MD5_DO( F4, c, d, a, b, p_input[ 2 ] + 0x2ad7d2bb, 15 );
00677 MD5_DO( F4, b, c, d, a, p_input[ 9 ] + 0xeb86d391, 21 );
00678
00679 p_md5->p_digest[ 0 ] += a;
00680 p_md5->p_digest[ 1 ] += b;
00681 p_md5->p_digest[ 2 ] += c;
00682 p_md5->p_digest[ 3 ] += d;
00683 }
00684 #endif
00685
00686
00687
00688
00689
00690
00691
00692 static void InitShuffle( struct shuffle_s *p_shuffle, uint32_t *p_sys_key,
00693 uint32_t i_version )
00694 {
00695 char p_secret1[] = "Tv!*";
00696 static char const p_secret2[] = "v8rhvsaAvOKMFfUH%798=[;."
00697 "f8677680a634ba87fnOIf)(*";
00698 unsigned int i;
00699
00700 p_shuffle->i_version = i_version;
00701
00702
00703 for( i = 0; i < 20; i++ )
00704 {
00705 struct md5_s md5;
00706 int32_t i_hash;
00707
00708 InitMD5( &md5 );
00709 AddMD5( &md5, (uint8_t *)p_sys_key, 16 );
00710 AddMD5( &md5, (uint8_t *)p_secret1, 4 );
00711 EndMD5( &md5 );
00712
00713 p_secret1[ 3 ]++;
00714
00715 REVERSE( md5.p_digest, 1 );
00716 i_hash = ((int32_t)U32_AT(md5.p_digest)) % 1024;
00717
00718 p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
00719 }
00720
00721
00722 for( i = 0; i < 4; i++ )
00723 {
00724 p_shuffle->p_bordel[ 4 * i ] = U32_AT(p_sys_key + i);
00725 memcpy( p_shuffle->p_bordel + 4 * i + 1, p_secret2 + 12 * i, 12 );
00726 REVERSE( p_shuffle->p_bordel + 4 * i + 1, 3 );
00727 }
00728 }
00729
00730
00731
00732
00733
00734
00735
00736 static void DoShuffle( struct shuffle_s *p_shuffle,
00737 uint32_t *p_buffer, uint32_t i_size )
00738 {
00739 struct md5_s md5;
00740 uint32_t p_big_bordel[ 16 ];
00741 uint32_t *p_bordel = p_shuffle->p_bordel;
00742 unsigned int i;
00743
00744 static uint32_t i_secret = 0;
00745
00746 static uint32_t p_secret1[] =
00747 {
00748 0xAAAAAAAA, 0x01757700, 0x00554580, 0x01724500, 0x00424580,
00749 0x01427700, 0x00000080, 0xC1D59D01, 0x80144981, 0x815C8901,
00750 0x80544981, 0x81D45D01, 0x00000080, 0x81A3BB03, 0x00A2AA82,
00751 0x01A3BB03, 0x0022A282, 0x813BA202, 0x00000080, 0x6D575737,
00752 0x4A5275A5, 0x6D525725, 0x4A5254A5, 0x6B725437, 0x00000080,
00753 0xD5DDB938, 0x5455A092, 0x5D95A013, 0x4415A192, 0xC5DD393A,
00754 0x00000080, 0x55555555
00755 };
00756
00757 static char p_secret2[] =
00758 "pbclevtug (p) Nccyr Pbzchgre, Vap. Nyy Evtugf Erfreirq.";
00759
00760 if( i_secret == 0 )
00761 {
00762 REVERSE( p_secret1, sizeof(p_secret1)/sizeof(p_secret1[ 0 ]) );
00763 for( ; p_secret2[ i_secret ] != '\0'; i_secret++ )
00764 {
00765 #define ROT13(c) (((c)>='A'&&(c)<='Z')?(((c)-'A'+13)%26)+'A':\
00766 ((c)>='a'&&(c)<='z')?(((c)-'a'+13)%26)+'a':c)
00767 p_secret2[ i_secret ] = ROT13(p_secret2[ i_secret ]);
00768 }
00769 i_secret++;
00770 }
00771
00772
00773
00774
00775 for( i = 0; i < 20; i++ )
00776 {
00777 uint8_t i_command, i_index;
00778
00779 if( !p_shuffle->p_commands[ i ] )
00780 {
00781 continue;
00782 }
00783
00784 i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
00785 i_index = p_shuffle->p_commands[ i ] & 0xff;
00786
00787 switch( i_command )
00788 {
00789 case 0x3:
00790 p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
00791 + p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
00792 break;
00793 case 0x2:
00794 p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
00795 break;
00796 case 0x1:
00797 p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
00798 break;
00799 default:
00800 p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
00801 break;
00802 }
00803 }
00804
00805 if( p_shuffle->i_version == 0x01000300 )
00806 {
00807 DoExtShuffle( p_bordel );
00808 }
00809
00810
00811
00812 InitMD5( &md5 );
00813 for( i = 0; i < 16; i++ )
00814 {
00815 p_big_bordel[ i ] = U32_AT(p_bordel + i);
00816 }
00817 AddMD5( &md5, (uint8_t *)p_big_bordel, 64 );
00818 if( p_shuffle->i_version == 0x01000300 )
00819 {
00820 AddMD5( &md5, (uint8_t *)p_secret1, sizeof(p_secret1) );
00821 AddMD5( &md5, (uint8_t *)p_secret2, i_secret );
00822 }
00823 EndMD5( &md5 );
00824
00825
00826 for( i = 0; i < i_size; i++ )
00827 {
00828 p_buffer[ i ] ^= md5.p_digest[ i ];
00829 }
00830 }
00831
00832
00833
00834
00835
00836
00837 static void DoExtShuffle( uint32_t * p_bordel )
00838 {
00839 uint32_t i_ret;
00840
00841 i_ret = FirstPass( p_bordel );
00842
00843 SecondPass( p_bordel, i_ret );
00844
00845 ThirdPass( p_bordel );
00846
00847 FourthPass( p_bordel );
00848 }
00849
00850 static uint32_t FirstPass( uint32_t * p_bordel )
00851 {
00852 uint32_t i, i_cmd, i_ret = 5;
00853
00854 TinyShuffle1( p_bordel );
00855
00856 for( ; ; )
00857 {
00858 for( ; ; )
00859 {
00860 p_bordel[ 1 ] += 0x10000000;
00861 p_bordel[ 3 ] += 0x12777;
00862
00863 if( (p_bordel[ 10 ] & 1) && i_ret )
00864 {
00865 i_ret--;
00866 p_bordel[ 1 ] -= p_bordel[ 2 ];
00867 p_bordel[ 11 ] += p_bordel[ 12 ];
00868 break;
00869 }
00870
00871 if( (p_bordel[ 1 ] + p_bordel[ 2 ]) >= 0x7D0 )
00872 {
00873 switch( ((p_bordel[ 3 ] ^ 0x567F) >> 2) & 7 )
00874 {
00875 case 0:
00876 for( i = 0; i < 3; i++ )
00877 {
00878 if( p_bordel[ i + 10 ] > 0x4E20 )
00879 {
00880 p_bordel[ i + 1 ] += p_bordel[ i + 2 ];
00881 }
00882 }
00883 break;
00884 case 4:
00885 p_bordel[ 1 ] -= p_bordel[ 2 ];
00886
00887 case 3:
00888 p_bordel[ 11 ] += p_bordel[ 12 ];
00889 break;
00890 case 6:
00891 p_bordel[ 3 ] ^= p_bordel[ 4 ];
00892
00893 case 8:
00894 p_bordel[ 13 ] &= p_bordel[ 14 ];
00895
00896 case 1:
00897 p_bordel[ 0 ] |= p_bordel[ 1 ];
00898 if( i_ret )
00899 {
00900 return i_ret;
00901 }
00902 break;
00903 }
00904
00905 break;
00906 }
00907 }
00908
00909 for( i = 0, i_cmd = 0; i < 16; i++ )
00910 {
00911 if( p_bordel[ i ] < p_bordel[ i_cmd ] )
00912 {
00913 i_cmd = i;
00914 }
00915 }
00916
00917 if( i_ret && i_cmd != 5 )
00918 {
00919 i_ret--;
00920 }
00921 else
00922 {
00923 if( i_cmd == 5 )
00924 {
00925 p_bordel[ 8 ] &= p_bordel[ 6 ] >> 1;
00926 p_bordel[ 3 ] <<= 1;
00927 }
00928
00929 for( i = 0; i < 3; i++ )
00930 {
00931 p_bordel[ 11 ] += 1;
00932 if( p_bordel[ 11 ] & 5 )
00933 {
00934 p_bordel[ 8 ] += p_bordel[ 9 ];
00935 }
00936 else if( i_ret )
00937 {
00938 i_ret--;
00939 i_cmd = 3;
00940 goto break2;
00941 }
00942 }
00943
00944 i_cmd = (p_bordel[ 15 ] + 0x93) >> 3;
00945 if( p_bordel[ 15 ] & 0x100 )
00946 {
00947 i_cmd ^= 0xDEAD;
00948 }
00949 }
00950
00951 switch( i_cmd & 3 )
00952 {
00953 case 0:
00954 while( p_bordel[ 11 ] & 1 )
00955 {
00956 p_bordel[ 11 ] >>= 1;
00957 p_bordel[ 12 ] += 1;
00958 }
00959
00960 case 2:
00961 p_bordel[ 14 ] -= 0x19FE;
00962 break;
00963 case 3:
00964 if( i_ret )
00965 {
00966 i_ret--;
00967 p_bordel[ 5 ] += 5;
00968 continue;
00969 }
00970 break;
00971 }
00972
00973 i_cmd = ((p_bordel[ 3 ] + p_bordel[ 4 ] + 10) >> 1) - p_bordel[ 4 ];
00974 break;
00975 }
00976 break2:
00977
00978 switch( i_cmd & 3 )
00979 {
00980 case 0:
00981 p_bordel[ 14 ] >>= 1;
00982 break;
00983 case 1:
00984 p_bordel[ 5 ] <<= 2;
00985 break;
00986 case 2:
00987 p_bordel[ 12 ] |= 5;
00988 break;
00989 case 3:
00990 p_bordel[ 15 ] &= 0x55;
00991 if( i_ret )
00992 {
00993 p_bordel[ 2 ] &= 0xB62FC;
00994 return i_ret;
00995 }
00996 break;
00997 }
00998
00999 TinyShuffle2( p_bordel );
01000
01001 return i_ret;
01002 }
01003
01004 static void SecondPass( uint32_t * p_bordel, uint32_t i_tmp )
01005 {
01006 uint32_t i, i_cmd, i_jc = 5;
01007
01008 TinyShuffle3( p_bordel );
01009
01010 for( i = 0, i_cmd = 0; i < 16; i++ )
01011 {
01012 if( p_bordel[ i ] > p_bordel[ i_cmd ] )
01013 {
01014 i_cmd = i;
01015 }
01016 }
01017
01018 switch( i_cmd )
01019 {
01020 case 0:
01021 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
01022 {
01023 p_bordel[ 5 ] += 1;
01024 }
01025 break;
01026 case 4:
01027 if( (p_bordel[ 9 ] & 0x7777) == 0x3333 )
01028 {
01029 p_bordel[ 5 ] -= 1;
01030 }
01031 else
01032 {
01033 i_jc--;
01034 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
01035 {
01036 p_bordel[ 5 ] += 1;
01037 }
01038 break;
01039 }
01040
01041 case 7:
01042 p_bordel[ 2 ] -= 1;
01043 p_bordel[ 1 ] -= p_bordel[ 5 ];
01044 for( i = 0; i < 3; i++ )
01045 {
01046 switch( p_bordel[ 1 ] & 3 )
01047 {
01048 case 0:
01049 p_bordel[ 1 ] += 1;
01050
01051 case 1:
01052 p_bordel[ 3 ] -= 8;
01053 break;
01054 case 2:
01055 p_bordel[ 13 ] &= 0xFEFEFEF7;
01056 break;
01057 case 3:
01058 p_bordel[ 8 ] |= 0x80080011;
01059 break;
01060 }
01061 }
01062 return;
01063 case 10:
01064 p_bordel[ 4 ] -= 1;
01065 p_bordel[ 5 ] += 1;
01066 p_bordel[ 6 ] -= 1;
01067 p_bordel[ 7 ] += 1;
01068 break;
01069 default:
01070 p_bordel[ 15 ] ^= 0x18547EFF;
01071 break;
01072 }
01073
01074 for( i = 3; i--; )
01075 {
01076 switch( ( p_bordel[ 12 ] + p_bordel[ 13 ] + p_bordel[ 6 ] ) % 5 )
01077 {
01078 case 0:
01079 p_bordel[ 12 ] -= 1;
01080
01081 case 1:
01082 p_bordel[ 12 ] -= 1;
01083 p_bordel[ 13 ] += 1;
01084 break;
01085 case 2:
01086 p_bordel[ 13 ] += 4;
01087
01088 case 3:
01089 p_bordel[ 12 ] -= 1;
01090 break;
01091 case 4:
01092 i_jc--;
01093 p_bordel[ 5 ] += 1;
01094 p_bordel[ 6 ] -= 1;
01095 p_bordel[ 7 ] += 1;
01096 i = 3;
01097 break;
01098 }
01099 }
01100
01101 TinyShuffle4( p_bordel );
01102
01103 for( ; ; )
01104 {
01105 TinyShuffle5( p_bordel );
01106
01107 switch( ( p_bordel[ 2 ] * 2 + 15 ) % 5 )
01108 {
01109 case 0:
01110 if( ( p_bordel[ 3 ] + i_tmp ) <=
01111 ( p_bordel[ 1 ] + p_bordel[ 15 ] ) )
01112 {
01113 p_bordel[ 3 ] += 1;
01114 }
01115 break;
01116 case 4:
01117 p_bordel[ 10 ] -= 0x13;
01118 break;
01119 case 3:
01120 p_bordel[ 5 ] >>= 2;
01121 break;
01122 }
01123
01124 if( !( p_bordel[ 2 ] & 1 ) || i_jc == 0 )
01125 {
01126 break;
01127 }
01128
01129 i_jc--;
01130 p_bordel[ 2 ] += 0x13;
01131 p_bordel[ 12 ] += 1;
01132 }
01133
01134 p_bordel[ 2 ] &= 0x10076000;
01135 }
01136
01137 static void ThirdPass( uint32_t * p_bordel )
01138 {
01139 uint32_t i_cmd;
01140
01141 i_cmd = ((p_bordel[ 7 ] + p_bordel[ 14 ] + 10) >> 1) - p_bordel[ 14 ];
01142 i_cmd = i_cmd % 10;
01143
01144 switch( i_cmd )
01145 {
01146 case 0:
01147 p_bordel[ 1 ] <<= 1;
01148 p_bordel[ 2 ] <<= 2;
01149 p_bordel[ 3 ] <<= 3;
01150 break;
01151 case 6:
01152 p_bordel[ i_cmd + 3 ] &= 0x5EDE36B;
01153 p_bordel[ 5 ] += p_bordel[ 8 ];
01154 p_bordel[ 4 ] += p_bordel[ 7 ];
01155 p_bordel[ 3 ] += p_bordel[ 6 ];
01156 p_bordel[ 2 ] += p_bordel[ 5 ];
01157
01158 case 2:
01159 p_bordel[ 1 ] += p_bordel[ 4 ];
01160 p_bordel[ 0 ] += p_bordel[ 3 ];
01161 TinyShuffle6( p_bordel );
01162 return;
01163 case 3:
01164 if( (p_bordel[ 11 ] & p_bordel[ 2 ]) > 0x211B )
01165 {
01166 p_bordel[ 6 ] += 1;
01167 }
01168 break;
01169 case 4:
01170 p_bordel[ 7 ] += 1;
01171
01172 case 5:
01173 p_bordel[ 9 ] ^= p_bordel[ 2 ];
01174 break;
01175 case 7:
01176 p_bordel[ 2 ] ^= (p_bordel[ 1 ] & p_bordel[ 13 ]);
01177 break;
01178 case 8:
01179 p_bordel[ 0 ] -= p_bordel[ 11 ] & p_bordel[ 15 ];
01180 return;
01181 case 9:
01182 p_bordel[ 6 ] >>= (p_bordel[ 14 ] & 3);
01183 break;
01184 }
01185
01186 SWAP( p_bordel[ 0 ], p_bordel[ 10 ] );
01187
01188 TinyShuffle6( p_bordel );
01189
01190 return;
01191 }
01192
01193 static void FourthPass( uint32_t * p_bordel )
01194 {
01195 uint32_t i, j;
01196
01197 TinyShuffle7( p_bordel );
01198
01199 switch( p_bordel[ 5 ] % 5)
01200 {
01201 case 0:
01202 p_bordel[ 0 ] += 1;
01203 break;
01204 case 2:
01205 p_bordel[ 11 ] ^= (p_bordel[ 3 ] + p_bordel[ 6 ] + p_bordel[ 8 ]);
01206 break;
01207 case 3:
01208 for( i = 4; i < 15 && (p_bordel[ i ] & 5) == 0; i++ )
01209 {
01210 SWAP( p_bordel[ i ], p_bordel[ 15 - i ] );
01211 }
01212 break;
01213 case 4:
01214 p_bordel[ 12 ] -= 1;
01215 p_bordel[ 13 ] += 1;
01216 p_bordel[ 2 ] -= 0x64;
01217 p_bordel[ 3 ] += 0x64;
01218 TinyShuffle8( p_bordel );
01219 return;
01220 }
01221
01222 for( i = 0, j = 0; i < 16; i++ )
01223 {
01224 if( p_bordel[ i ] > p_bordel[ j ] )
01225 {
01226 j = i;
01227 }
01228 }
01229
01230 switch( p_bordel[ j ] % 100 )
01231 {
01232 case 0:
01233 SWAP( p_bordel[ 0 ], p_bordel[ j ] );
01234 break;
01235 case 8:
01236 p_bordel[ 1 ] >>= 1;
01237 p_bordel[ 2 ] <<= 1;
01238 p_bordel[ 14 ] >>= 3;
01239 p_bordel[ 15 ] <<= 4;
01240 break;
01241 case 57:
01242 p_bordel[ j ] += p_bordel[ 13 ];
01243 break;
01244 case 76:
01245 p_bordel[ 1 ] += 0x20E;
01246 p_bordel[ 5 ] += 0x223D;
01247 p_bordel[ 13 ] -= 0x576;
01248 p_bordel[ 15 ] += 0x576;
01249 return;
01250 case 91:
01251 p_bordel[ 2 ] -= 0x64;
01252 p_bordel[ 3 ] += 0x64;
01253 p_bordel[ 12 ] -= 1;
01254 p_bordel[ 13 ] += 1;
01255 break;
01256 case 99:
01257 p_bordel[ 0 ] += 1;
01258 p_bordel[ j ] += p_bordel[ 13 ];
01259 break;
01260 }
01261
01262 TinyShuffle8( p_bordel );
01263 }
01264
01265
01266
01267
01268
01269
01270 static void TinyShuffle1( uint32_t * p_bordel )
01271 {
01272 uint32_t i_cmd = (p_bordel[ 5 ] + 10) >> 2;
01273
01274 if( p_bordel[ 5 ] > 0x7D0 )
01275 {
01276 i_cmd -= 0x305;
01277 }
01278
01279 switch( i_cmd & 3 )
01280 {
01281 case 0:
01282 p_bordel[ 5 ] += 5;
01283 break;
01284 case 1:
01285 p_bordel[ 4 ] -= 1;
01286 break;
01287 case 2:
01288 if( p_bordel[ 4 ] & 5 )
01289 {
01290 p_bordel[ 1 ] ^= 0x4D;
01291 }
01292
01293 case 3:
01294 p_bordel[ 12 ] += 5;
01295 break;
01296 }
01297 }
01298
01299 static void TinyShuffle2( uint32_t * p_bordel )
01300 {
01301 uint32_t i, j;
01302
01303 for( i = 0, j = 0; i < 16; i++ )
01304 {
01305 if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) )
01306 {
01307 j = i;
01308 }
01309 }
01310
01311 if( j > 5 )
01312 {
01313 for( ; j < 15; j++ )
01314 {
01315 p_bordel[ j ] += p_bordel[ j + 1 ];
01316 }
01317 }
01318 else
01319 {
01320 p_bordel[ 2 ] &= 0xB62FC;
01321 }
01322 }
01323
01324 static void TinyShuffle3( uint32_t * p_bordel )
01325 {
01326 uint32_t i_cmd = p_bordel[ 6 ] + 0x194B;
01327
01328 if( p_bordel[ 6 ] > 0x2710 )
01329 {
01330 i_cmd >>= 1;
01331 }
01332
01333 switch( i_cmd & 3 )
01334 {
01335 case 1:
01336 p_bordel[ 3 ] += 0x19FE;
01337 break;
01338 case 2:
01339 p_bordel[ 7 ] -= p_bordel[ 3 ] >> 2;
01340
01341 case 0:
01342 p_bordel[ 5 ] ^= 0x248A;
01343 break;
01344 }
01345 }
01346
01347 static void TinyShuffle4( uint32_t * p_bordel )
01348 {
01349 uint32_t i, j;
01350
01351 for( i = 0, j = 0; i < 16; i++ )
01352 {
01353 if( p_bordel[ i ] < p_bordel[ j ] )
01354 {
01355 j = i;
01356 }
01357 }
01358
01359 if( (p_bordel[ j ] % (j + 1)) > 10 )
01360 {
01361 p_bordel[ 1 ] -= 1;
01362 p_bordel[ 2 ] += 0x13;
01363 p_bordel[ 12 ] += 1;
01364 }
01365 }
01366
01367 static void TinyShuffle5( uint32_t * p_bordel )
01368 {
01369 uint32_t i;
01370
01371 p_bordel[ 2 ] &= 0x7F3F;
01372
01373 for( i = 0; i < 5; i++ )
01374 {
01375 switch( ( p_bordel[ 2 ] + 10 + i ) % 5 )
01376 {
01377 case 0:
01378 p_bordel[ 12 ] &= p_bordel[ 2 ];
01379
01380 case 1:
01381 p_bordel[ 3 ] ^= p_bordel[ 15 ];
01382 break;
01383 case 2:
01384 p_bordel[ 15 ] += 0x576;
01385
01386 case 3:
01387 p_bordel[ 7 ] -= 0x2D;
01388
01389 case 4:
01390 p_bordel[ 1 ] <<= 1;
01391 break;
01392 }
01393 }
01394 }
01395
01396 static void TinyShuffle6( uint32_t * p_bordel )
01397 {
01398 uint32_t i, j;
01399
01400 for( i = 0; i < 8; i++ )
01401 {
01402 j = p_bordel[ 3 ] & 0x7514 ? 5 : 7;
01403 SWAP( p_bordel[ i ], p_bordel[ i + j ] );
01404 }
01405 }
01406
01407 static void TinyShuffle7( uint32_t * p_bordel )
01408 {
01409 uint32_t i;
01410
01411 i = (((p_bordel[ 9 ] + p_bordel[ 15 ] + 12) >> 2) - p_bordel[ 4 ]) & 7;
01412
01413 while( i-- )
01414 {
01415 SWAP( p_bordel[ i ], p_bordel[ i + 3 ] );
01416 }
01417
01418 SWAP( p_bordel[ 1 ], p_bordel[ 10 ] );
01419 }
01420
01421 static void TinyShuffle8( uint32_t * p_bordel )
01422 {
01423 uint32_t i;
01424
01425 i = (p_bordel[ 0 ] & p_bordel[ 6 ]) & 0xF;
01426
01427 switch( p_bordel[ i ] % 1000 )
01428 {
01429 case 7:
01430 if( (p_bordel[ i ] & 0x777) > (p_bordel[ 7 ] & 0x5555) )
01431 {
01432 p_bordel[ i ] ^= p_bordel[ 5 ] & p_bordel[ 3 ];
01433 }
01434 break;
01435 case 19:
01436 p_bordel[ 15 ] &= 0x5555;
01437 break;
01438 case 93:
01439 p_bordel[ i ] ^= p_bordel[ 15 ];
01440 break;
01441 case 100:
01442 SWAP( p_bordel[ 0 ], p_bordel[ 3 ] );
01443 SWAP( p_bordel[ 1 ], p_bordel[ 6 ] );
01444 SWAP( p_bordel[ 3 ], p_bordel[ 6 ] );
01445 SWAP( p_bordel[ 4 ], p_bordel[ 9 ] );
01446 SWAP( p_bordel[ 5 ], p_bordel[ 8 ] );
01447 SWAP( p_bordel[ 6 ], p_bordel[ 7 ] );
01448 SWAP( p_bordel[ 13 ], p_bordel[ 14 ] );
01449 break;
01450 case 329:
01451 p_bordel[ i ] += p_bordel[ 1 ] ^ 0x80080011;
01452 p_bordel[ i ] += p_bordel[ 2 ] ^ 0xBEEFDEAD;
01453 p_bordel[ i ] += p_bordel[ 3 ] ^ 0x8765F444;
01454 p_bordel[ i ] += p_bordel[ 4 ] ^ 0x78145326;
01455 break;
01456 case 567:
01457 p_bordel[ 12 ] -= p_bordel[ i ];
01458 p_bordel[ 13 ] += p_bordel[ i ];
01459 break;
01460 case 612:
01461 p_bordel[ i ] += p_bordel[ 1 ];
01462 p_bordel[ i ] -= p_bordel[ 7 ];
01463 p_bordel[ i ] -= p_bordel[ 8 ];
01464 p_bordel[ i ] += p_bordel[ 9 ];
01465 p_bordel[ i ] += p_bordel[ 13 ];
01466 break;
01467 case 754:
01468 i = __MIN( i, 12 );
01469 p_bordel[ i + 1 ] >>= 1;
01470 p_bordel[ i + 2 ] <<= 4;
01471 p_bordel[ i + 3 ] >>= 3;
01472 break;
01473 case 777:
01474 p_bordel[ 1 ] += 0x20E;
01475 p_bordel[ 5 ] += 0x223D;
01476 p_bordel[ 13 ] -= 0x576;
01477 p_bordel[ 15 ] += 0x576;
01478 break;
01479 case 981:
01480 if( (p_bordel[ i ] ^ 0x8765F441) < 0x2710 )
01481 {
01482 SWAP( p_bordel[ 0 ], p_bordel[ 1 ] );
01483 }
01484 else
01485 {
01486 SWAP( p_bordel[ 1 ], p_bordel[ 11 ] );
01487 }
01488 break;
01489 }
01490 }
01491
01492
01493
01494
01495
01496
01497 static int GetSystemKey( uint32_t *p_sys_key, vlc_bool_t b_ipod )
01498 {
01499 static char const p_secret1[ 8 ] = "YuaFlafu";
01500 static char const p_secret2[ 8 ] = "zPif98ga";
01501 struct md5_s md5;
01502 int64_t i_ipod_id;
01503 uint32_t p_system_hash[ 4 ];
01504
01505
01506 if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) ||
01507 ( b_ipod && GetiPodID( &i_ipod_id ) ) )
01508 {
01509 return -1;
01510 }
01511
01512
01513
01514 InitMD5( &md5 );
01515 AddMD5( &md5, p_secret1, 8 );
01516
01517 if( !b_ipod )
01518 {
01519 AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
01520 AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
01521 AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
01522 AddMD5( &md5, p_secret2, 8 );
01523 }
01524 else
01525 {
01526 i_ipod_id = U64_AT(&i_ipod_id);
01527 AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
01528 AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
01529 AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
01530 }
01531
01532 EndMD5( &md5 );
01533
01534 memcpy( p_sys_key, md5.p_digest, 16 );
01535
01536 return 0;
01537 }
01538
01539 #ifdef WIN32
01540 # define DRMS_DIRNAME "drms"
01541 #else
01542 # define DRMS_DIRNAME ".drms"
01543 #endif
01544
01545
01546
01547
01548
01549
01550
01551 static int WriteUserKey( void *_p_drms, uint32_t *p_user_key )
01552 {
01553 struct drms_s *p_drms = (struct drms_s *)_p_drms;
01554 FILE *file;
01555 int i_ret = -1;
01556 char psz_path[ PATH_MAX ];
01557
01558 snprintf( psz_path, PATH_MAX - 1,
01559 "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
01560
01561 #if defined( HAVE_ERRNO_H )
01562 # if defined( WIN32 )
01563 if( !mkdir( psz_path ) || errno == EEXIST )
01564 # else
01565 if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
01566 # endif
01567 #else
01568 if( !mkdir( psz_path ) )
01569 #endif
01570 {
01571 snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d",
01572 p_drms->psz_homedir, p_drms->i_user, p_drms->i_key );
01573
01574 file = fopen( psz_path, "wb" );
01575 if( file != NULL )
01576 {
01577 i_ret = fwrite( p_user_key, sizeof(uint32_t),
01578 4, file ) == 4 ? 0 : -1;
01579 fclose( file );
01580 }
01581 }
01582
01583 return i_ret;
01584 }
01585
01586
01587
01588
01589
01590
01591 static int ReadUserKey( void *_p_drms, uint32_t *p_user_key )
01592 {
01593 struct drms_s *p_drms = (struct drms_s *)_p_drms;
01594 FILE *file;
01595 int i_ret = -1;
01596 char psz_path[ PATH_MAX ];
01597
01598 snprintf( psz_path, PATH_MAX - 1,
01599 "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir,
01600 p_drms->i_user, p_drms->i_key );
01601
01602 file = fopen( psz_path, "rb" );
01603 if( file != NULL )
01604 {
01605 i_ret = fread( p_user_key, sizeof(uint32_t),
01606 4, file ) == 4 ? 0 : -1;
01607 fclose( file );
01608 }
01609
01610 return i_ret;
01611 }
01612
01613
01614
01615
01616
01617
01618
01619
01620 static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
01621 {
01622 static char const p_secret[] = "mUfnpognadfgf873";
01623 struct drms_s *p_drms = (struct drms_s *)_p_drms;
01624 struct aes_s aes;
01625 struct shuffle_s shuffle;
01626 uint32_t i, y;
01627 uint32_t *p_sci_data;
01628 uint32_t i_user, i_key;
01629 uint32_t p_sys_key[ 4 ];
01630 uint32_t i_sci_size, i_blocks, i_remaining;
01631 uint32_t *p_sci0, *p_sci1, *p_buffer;
01632 uint32_t p_sci_key[ 4 ];
01633 char *psz_ipod;
01634 int i_ret = -1;
01635
01636 if( !ReadUserKey( p_drms, p_user_key ) )
01637 {
01638 REVERSE( p_user_key, 4 );
01639 return 0;
01640 }
01641
01642 psz_ipod = getenv( "IPOD" );
01643
01644 if( GetSystemKey( p_sys_key, psz_ipod ? VLC_TRUE : VLC_FALSE ) )
01645 {
01646 return -1;
01647 }
01648
01649 if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
01650 {
01651 return -1;
01652 }
01653
01654
01655
01656
01657
01658 i_blocks = (i_sci_size - 4) / 16;
01659 i_remaining = (i_sci_size - 4) - (i_blocks * 16);
01660 p_buffer = p_sci_data + 1;
01661
01662
01663 InitAES( &aes, p_sys_key );
01664 REVERSE( p_sys_key, 4 );
01665 REVERSE( p_sci_data, 1 );
01666 InitShuffle( &shuffle, p_sys_key, p_sci_data[ 0 ] );
01667
01668 memcpy( p_sci_key, p_secret, 16 );
01669 REVERSE( p_sci_key, 4 );
01670
01671 while( i_blocks-- )
01672 {
01673 uint32_t p_tmp[ 4 ];
01674
01675 REVERSE( p_buffer, 4 );
01676 DecryptAES( &aes, p_tmp, p_buffer );
01677 BlockXOR( p_tmp, p_sci_key, p_tmp );
01678
01679
01680 memcpy( p_sci_key, p_buffer, 16 );
01681
01682
01683 DoShuffle( &shuffle, p_tmp, 4 );
01684
01685
01686 memcpy( p_buffer, p_tmp, 16 );
01687
01688 p_buffer += 4;
01689 }
01690
01691 if( i_remaining >= 4 )
01692 {
01693 i_remaining /= 4;
01694 REVERSE( p_buffer, i_remaining );
01695 DoShuffle( &shuffle, p_buffer, i_remaining );
01696 }
01697
01698
01699
01700
01701
01702
01703 y = 0;
01704 REVERSE( p_sci_data + 5, 1 );
01705 i = U32_AT( p_sci_data + 5 );
01706 i_sci_size -= 22 * sizeof(uint32_t);
01707 p_sci1 = p_sci_data + 22;
01708 p_sci0 = NULL;
01709
01710 while( i_sci_size >= 20 && i > 0 )
01711 {
01712 if( p_sci0 == NULL )
01713 {
01714 i_sci_size -= 18 * sizeof(uint32_t);
01715 if( i_sci_size < 20 )
01716 {
01717 break;
01718 }
01719
01720 p_sci0 = p_sci1;
01721 REVERSE( p_sci1 + 17, 1 );
01722 y = U32_AT( p_sci1 + 17 );
01723 p_sci1 += 18;
01724 }
01725
01726 if( !y )
01727 {
01728 i--;
01729 p_sci0 = NULL;
01730 continue;
01731 }
01732
01733 i_user = U32_AT( p_sci0 );
01734 i_key = U32_AT( p_sci1 );
01735 REVERSE( &i_user, 1 );
01736 REVERSE( &i_key, 1 );
01737 if( i_user == p_drms->i_user && ( ( i_key == p_drms->i_key ) ||
01738 ( !p_drms->i_key && ( p_sci1 == (p_sci0 + 18) ) ) ) )
01739 {
01740 memcpy( p_user_key, p_sci1 + 1, 16 );
01741 REVERSE( p_sci1 + 1, 4 );
01742 WriteUserKey( p_drms, p_sci1 + 1 );
01743 i_ret = 0;
01744 break;
01745 }
01746
01747 y--;
01748 p_sci1 += 5;
01749 i_sci_size -= 5 * sizeof(uint32_t);
01750 }
01751
01752 free( p_sci_data );
01753
01754 return i_ret;
01755 }
01756
01757
01758
01759
01760
01761
01762 static int GetSCIData( char *psz_ipod, uint32_t **pp_sci,
01763 uint32_t *pi_sci_size )
01764 {
01765 FILE *file;
01766 char *psz_path = NULL;
01767 char p_tmp[ PATH_MAX ];
01768 int i_ret = -1;
01769
01770 if( psz_ipod == NULL )
01771 {
01772 #ifdef WIN32
01773 char *p_filename = "\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb";
01774 typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
01775 LPSTR );
01776 HINSTANCE shfolder_dll = NULL;
01777 SHGETFOLDERPATH dSHGetFolderPath = NULL;
01778
01779 if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
01780 {
01781 dSHGetFolderPath =
01782 (SHGETFOLDERPATH)GetProcAddress( shfolder_dll,
01783 _T("SHGetFolderPathA") );
01784 }
01785
01786 if( dSHGetFolderPath != NULL &&
01787 SUCCEEDED( dSHGetFolderPath( NULL, CSIDL_COMMON_APPDATA,
01788 NULL, 0, p_tmp ) ) )
01789 {
01790 strncat( p_tmp, p_filename, min( strlen( p_filename ),
01791 (sizeof(p_tmp)/sizeof(p_tmp[0]) - 1) -
01792 strlen( p_tmp ) ) );
01793 psz_path = p_tmp;
01794 }
01795
01796 if( shfolder_dll != NULL )
01797 {
01798 FreeLibrary( shfolder_dll );
01799 }
01800 #endif
01801 }
01802 else
01803 {
01804 #define ISCINFO "iSCInfo"
01805 if( strstr( psz_ipod, ISCINFO ) == NULL )
01806 {
01807 snprintf( p_tmp, sizeof(p_tmp)/sizeof(p_tmp[0]) - 1,
01808 "%s/iPod_Control/iTunes/" ISCINFO "2", psz_ipod );
01809 psz_path = p_tmp;
01810 }
01811 else
01812 {
01813 psz_path = psz_ipod;
01814 }
01815 }
01816
01817 if( psz_path == NULL )
01818 {
01819 return -1;
01820 }
01821
01822 file = fopen( psz_path, "rb" );
01823 if( file != NULL )
01824 {
01825 struct stat st;
01826
01827 if( !fstat( fileno( file ), &st ) && st.st_size >= 4 )
01828 {
01829 *pp_sci = malloc( st.st_size );
01830 if( *pp_sci != NULL )
01831 {
01832 if( fread( *pp_sci, 1, st.st_size,
01833 file ) == (size_t)st.st_size )
01834 {
01835 *pi_sci_size = st.st_size;
01836 i_ret = 0;
01837 }
01838 else
01839 {
01840 free( (void *)*pp_sci );
01841 *pp_sci = NULL;
01842 }
01843 }
01844 }
01845
01846 fclose( file );
01847 }
01848
01849 return i_ret;
01850 }
01851
01852
01853
01854
01855
01856
01857
01858 static int HashSystemInfo( uint32_t *p_system_hash )
01859 {
01860 struct md5_s md5;
01861 int i_ret = 0;
01862
01863 #ifdef WIN32
01864 HKEY i_key;
01865 unsigned int i;
01866 DWORD i_size;
01867 DWORD i_serial;
01868 LPBYTE p_reg_buf;
01869
01870 static LPCTSTR p_reg_keys[ 3 ][ 2 ] =
01871 {
01872 {
01873 _T("HARDWARE\\DESCRIPTION\\System"),
01874 _T("SystemBiosVersion")
01875 },
01876
01877 {
01878 _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
01879 _T("ProcessorNameString")
01880 },
01881
01882 {
01883 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
01884 _T("ProductId")
01885 }
01886 };
01887
01888 InitMD5( &md5 );
01889
01890 AddMD5( &md5, "cache-control", 13 );
01891 AddMD5( &md5, "Ethernet", 8 );
01892
01893 GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
01894 NULL, NULL, NULL, 0 );
01895 AddMD5( &md5, (uint8_t *)&i_serial, 4 );
01896
01897 for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
01898 {
01899 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
01900 0, KEY_READ, &i_key ) != ERROR_SUCCESS )
01901 {
01902 continue;
01903 }
01904
01905 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
01906 NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
01907 {
01908 RegCloseKey( i_key );
01909 continue;
01910 }
01911
01912 p_reg_buf = malloc( i_size );
01913
01914 if( p_reg_buf != NULL )
01915 {
01916 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
01917 NULL, NULL, p_reg_buf,
01918 &i_size ) == ERROR_SUCCESS )
01919 {
01920 AddMD5( &md5, (uint8_t *)p_reg_buf, i_size );
01921 }
01922
01923 free( p_reg_buf );
01924 }
01925
01926 RegCloseKey( i_key );
01927 }
01928
01929 #else
01930 InitMD5( &md5 );
01931 i_ret = -1;
01932 #endif
01933
01934 EndMD5( &md5 );
01935 memcpy( p_system_hash, md5.p_digest, 16 );
01936
01937 return i_ret;
01938 }
01939
01940
01941
01942
01943
01944
01945 static int GetiPodID( int64_t *p_ipod_id )
01946 {
01947 int i_ret = -1;
01948
01949 #define PROD_NAME "iPod"
01950 #define VENDOR_NAME "Apple Computer, Inc."
01951
01952 char *psz_ipod_id = getenv( "IPODID" );
01953 if( psz_ipod_id != NULL )
01954 {
01955 *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
01956 return 0;
01957 }
01958
01959 #ifdef SYS_DARWIN
01960 CFTypeRef value;
01961 mach_port_t port;
01962 io_object_t device;
01963 io_iterator_t iterator;
01964 CFMutableDictionaryRef match_dic;
01965 CFMutableDictionaryRef smatch_dic;
01966
01967 if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
01968 {
01969 smatch_dic = IOServiceMatching( "IOFireWireUnit" );
01970 match_dic = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
01971 &kCFTypeDictionaryKeyCallBacks,
01972 &kCFTypeDictionaryValueCallBacks );
01973
01974 if( smatch_dic != NULL && match_dic != NULL )
01975 {
01976 CFDictionarySetValue( smatch_dic,
01977 CFSTR("FireWire Vendor Name"),
01978 CFSTR(VENDOR_NAME) );
01979 CFDictionarySetValue( smatch_dic,
01980 CFSTR("FireWire Product Name"),
01981 CFSTR(PROD_NAME) );
01982
01983 CFDictionarySetValue( match_dic,
01984 CFSTR(kIOPropertyMatchKey),
01985 smatch_dic );
01986
01987 if( IOServiceGetMatchingServices( port, match_dic,
01988 &iterator ) == KERN_SUCCESS )
01989 {
01990 while( ( device = IOIteratorNext( iterator ) ) != NULL )
01991 {
01992 value = IORegistryEntryCreateCFProperty( device,
01993 CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );
01994
01995 if( value != NULL )
01996 {
01997 if( CFGetTypeID( value ) == CFNumberGetTypeID() )
01998 {
01999 int64_t i_ipod_id;
02000 CFNumberGetValue( (CFNumberRef)value,
02001 kCFNumberLongLongType,
02002 &i_ipod_id );
02003 *p_ipod_id = i_ipod_id;
02004 i_ret = 0;
02005 }
02006
02007 CFRelease( value );
02008 }
02009
02010 IOObjectRelease( device );
02011
02012 if( !i_ret ) break;
02013 }
02014
02015 IOObjectRelease( iterator );
02016 }
02017 }
02018
02019 mach_port_deallocate( mach_task_self(), port );
02020 }
02021
02022 #elif HAVE_SYSFS_LIBSYSFS_H
02023 struct sysfs_bus *bus = NULL;
02024 struct dlist *devlist = NULL;
02025 struct dlist *attributes = NULL;
02026 struct sysfs_device *curdev = NULL;
02027 struct sysfs_attribute *curattr = NULL;
02028
02029 bus = sysfs_open_bus( "ieee1394" );
02030 if( bus != NULL )
02031 {
02032 devlist = sysfs_get_bus_devices( bus );
02033 if( devlist != NULL )
02034 {
02035 dlist_for_each_data( devlist, curdev, struct sysfs_device )
02036 {
02037 attributes = sysfs_get_device_attributes( curdev );
02038 if( attributes != NULL )
02039 {
02040 dlist_for_each_data( attributes, curattr,
02041 struct sysfs_attribute )
02042 {
02043 if( ( strcmp( curattr->name, "model_name" ) == 0 ) &&
02044 ( strncmp( curattr->value, PROD_NAME,
02045 sizeof(PROD_NAME) ) == 0 ) )
02046 {
02047 *p_ipod_id = strtoll( curdev->name, NULL, 16 );
02048 i_ret = 0;
02049 break;
02050 }
02051 }
02052 }
02053
02054 if( !i_ret ) break;
02055 }
02056 }
02057
02058 sysfs_close_bus( bus );
02059 }
02060 #endif
02061
02062 return i_ret;
02063 }
02064
02065 #else
02066
02067 void *drms_alloc( char *psz_homedir ){ return 0; }
02068 void drms_free( void *a ){}
02069 void drms_decrypt( void *a, uint32_t *b, uint32_t c ){}
02070 int drms_init( void *a, uint32_t b, uint8_t *c, uint32_t d ){ return -1; }
02071
02072 #endif