drms.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:60k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * drms.c: DRMS
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 VideoLAN
  5.  * $Id: drms.c 8958 2004-10-08 10:36:25Z gbazin $
  6.  *
  7.  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
  8.  *          Sam Hocevar <sam@zoy.org>
  9.  *
  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.
  14.  *
  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.
  19.  *
  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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. #include <stdlib.h>                                      /* malloc(), free() */
  25. #ifdef WIN32
  26. #   include <io.h>
  27. #else
  28. #   include <stdio.h>
  29. #endif
  30. #ifdef __VLC__
  31. #   include <vlc/vlc.h>
  32. #   include "libmp4.h"
  33. #else
  34. #   include "drmsvl.h"
  35. #endif
  36. #ifdef HAVE_ERRNO_H
  37. #   include <errno.h>
  38. #endif
  39. #ifdef WIN32
  40. #   if !defined( UNDER_CE )
  41. #       include <direct.h>
  42. #   endif
  43. #   include <tchar.h>
  44. #   include <shlobj.h>
  45. #   include <windows.h>
  46. #endif
  47. #ifdef HAVE_SYS_STAT_H
  48. #   include <sys/stat.h>
  49. #endif
  50. #ifdef HAVE_SYS_TYPES_H
  51. #   include <sys/types.h>
  52. #endif
  53. /* In Solaris (and perhaps others) PATH_MAX is in limits.h. */
  54. #ifdef HAVE_LIMITS_H
  55. #   include <limits.h>
  56. #endif
  57. #ifdef SYS_DARWIN
  58. #   include <mach/mach.h>
  59. #   include <IOKit/IOKitLib.h>
  60. #   include <CoreFoundation/CFNumber.h>
  61. #endif
  62. #ifdef HAVE_SYSFS_LIBSYSFS_H
  63. #   include <sysfs/libsysfs.h>
  64. #endif
  65. #include "drms.h"
  66. #include "drmstables.h"
  67. #if !defined( UNDER_CE )
  68. /*****************************************************************************
  69.  * aes_s: AES keys structure
  70.  *****************************************************************************
  71.  * This structure stores a set of keys usable for encryption and decryption
  72.  * with the AES/Rijndael algorithm.
  73.  *****************************************************************************/
  74. struct aes_s
  75. {
  76.     uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
  77.     uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
  78. };
  79. /*****************************************************************************
  80.  * md5_s: MD5 message structure
  81.  *****************************************************************************
  82.  * This structure stores the static information needed to compute an MD5
  83.  * hash. It has an extra data buffer to allow non-aligned writes.
  84.  *****************************************************************************/
  85. struct md5_s
  86. {
  87.     uint64_t i_bits;      /* Total written bits */
  88.     uint32_t p_digest[4]; /* The MD5 digest */
  89.     uint32_t p_data[16];  /* Buffer to cache non-aligned writes */
  90. };
  91. /*****************************************************************************
  92.  * shuffle_s: shuffle structure
  93.  *****************************************************************************
  94.  * This structure stores the static information needed to shuffle data using
  95.  * a custom algorithm.
  96.  *****************************************************************************/
  97. struct shuffle_s
  98. {
  99.     uint32_t i_version;
  100.     uint32_t p_commands[ 20 ];
  101.     uint32_t p_bordel[ 16 ];
  102. };
  103. #define SWAP( a, b ) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
  104. /*****************************************************************************
  105.  * drms_s: DRMS structure
  106.  *****************************************************************************
  107.  * This structure stores the static information needed to decrypt DRMS data.
  108.  *****************************************************************************/
  109. struct drms_s
  110. {
  111.     uint32_t i_user;
  112.     uint32_t i_key;
  113.     uint8_t  p_iviv[ 16 ];
  114.     uint8_t *p_name;
  115.     uint32_t p_key[ 4 ];
  116.     struct aes_s aes;
  117.     char     psz_homedir[ PATH_MAX ];
  118. };
  119. /*****************************************************************************
  120.  * Local prototypes
  121.  *****************************************************************************/
  122. static void InitAES       ( struct aes_s *, uint32_t * );
  123. static void DecryptAES    ( struct aes_s *, uint32_t *, const uint32_t * );
  124. static void InitMD5       ( struct md5_s * );
  125. static void AddMD5        ( struct md5_s *, const uint8_t *, uint32_t );
  126. static void EndMD5        ( struct md5_s * );
  127. static void Digest        ( struct md5_s *, uint32_t * );
  128. static void InitShuffle   ( struct shuffle_s *, uint32_t *, uint32_t );
  129. static void DoShuffle     ( struct shuffle_s *, uint32_t *, uint32_t );
  130. static uint32_t FirstPass ( uint32_t * );
  131. static void SecondPass    ( uint32_t *, uint32_t );
  132. static void ThirdPass     ( uint32_t * );
  133. static void FourthPass    ( uint32_t * );
  134. static void TinyShuffle1  ( uint32_t * );
  135. static void TinyShuffle2  ( uint32_t * );
  136. static void TinyShuffle3  ( uint32_t * );
  137. static void TinyShuffle4  ( uint32_t * );
  138. static void TinyShuffle5  ( uint32_t * );
  139. static void TinyShuffle6  ( uint32_t * );
  140. static void TinyShuffle7  ( uint32_t * );
  141. static void TinyShuffle8  ( uint32_t * );
  142. static void DoExtShuffle  ( uint32_t * );
  143. static int GetSystemKey   ( uint32_t *, vlc_bool_t );
  144. static int WriteUserKey   ( void *, uint32_t * );
  145. static int ReadUserKey    ( void *, uint32_t * );
  146. static int GetUserKey     ( void *, uint32_t * );
  147. static int GetSCIData     ( char *, uint32_t **, uint32_t * );
  148. static int HashSystemInfo ( uint32_t * );
  149. static int GetiPodID      ( int64_t * );
  150. #ifdef WORDS_BIGENDIAN
  151. /*****************************************************************************
  152.  * Reverse: reverse byte order
  153.  *****************************************************************************/
  154. static inline void Reverse( uint32_t *p_buffer, int n )
  155. {
  156.     int i;
  157.     for( i = 0; i < n; i++ )
  158.     {
  159.         p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
  160.     }
  161. }
  162. #    define REVERSE( p, n ) Reverse( p, n )
  163. #else
  164. #    define REVERSE( p, n )
  165. #endif
  166. /*****************************************************************************
  167.  * BlockXOR: XOR two 128 bit blocks
  168.  *****************************************************************************/
  169. static inline void BlockXOR( uint32_t *p_dest, uint32_t *p_s1, uint32_t *p_s2 )
  170. {
  171.     int i;
  172.     for( i = 0; i < 4; i++ )
  173.     {
  174.         p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
  175.     }
  176. }
  177. /*****************************************************************************
  178.  * drms_alloc: allocate a DRMS structure
  179.  *****************************************************************************/
  180. void *drms_alloc( char *psz_homedir )
  181. {
  182.     struct drms_s *p_drms;
  183.     p_drms = malloc( sizeof(struct drms_s) );
  184.     if( p_drms == NULL )
  185.     {
  186.         return NULL;
  187.     }
  188.     memset( p_drms, 0, sizeof(struct drms_s) );
  189.     strncpy( p_drms->psz_homedir, psz_homedir, PATH_MAX );
  190.     p_drms->psz_homedir[ PATH_MAX - 1 ] = '';
  191.     return (void *)p_drms;
  192. }
  193. /*****************************************************************************
  194.  * drms_free: free a previously allocated DRMS structure
  195.  *****************************************************************************/
  196. void drms_free( void *_p_drms )
  197. {
  198.     struct drms_s *p_drms = (struct drms_s *)_p_drms;
  199.     if( p_drms->p_name != NULL )
  200.     {
  201.         free( (void *)p_drms->p_name );
  202.     }
  203.     free( p_drms );
  204. }
  205. /*****************************************************************************
  206.  * drms_decrypt: unscramble a chunk of data
  207.  *****************************************************************************/
  208. void drms_decrypt( void *_p_drms, uint32_t *p_buffer, uint32_t i_bytes )
  209. {
  210.     struct drms_s *p_drms = (struct drms_s *)_p_drms;
  211.     uint32_t p_key[ 4 ];
  212.     unsigned int i_blocks;
  213.     /* AES is a block cypher, round down the byte count */
  214.     i_blocks = i_bytes / 16;
  215.     i_bytes = i_blocks * 16;
  216.     /* Initialise the key */
  217.     memcpy( p_key, p_drms->p_key, 16 );
  218.     /* Unscramble */
  219.     while( i_blocks-- )
  220.     {
  221.         uint32_t p_tmp[ 4 ];
  222.         REVERSE( p_buffer, 4 );
  223.         DecryptAES( &p_drms->aes, p_tmp, p_buffer );
  224.         BlockXOR( p_tmp, p_key, p_tmp );
  225.         /* Use the previous scrambled data as the key for next block */
  226.         memcpy( p_key, p_buffer, 16 );
  227.         /* Copy unscrambled data back to the buffer */
  228.         memcpy( p_buffer, p_tmp, 16 );
  229.         REVERSE( p_buffer, 4 );
  230.         p_buffer += 4;
  231.     }
  232. }
  233. /*****************************************************************************
  234.  * drms_init: initialise a DRMS structure
  235.  *****************************************************************************/
  236. int drms_init( void *_p_drms, uint32_t i_type,
  237.                uint8_t *p_info, uint32_t i_len )
  238. {
  239.     struct drms_s *p_drms = (struct drms_s *)_p_drms;
  240.     int i_ret = 0;
  241.     switch( i_type )
  242.     {
  243.         case FOURCC_user:
  244.             if( i_len < sizeof(p_drms->i_user) )
  245.             {
  246.                 i_ret = -1;
  247.                 break;
  248.             }
  249.             p_drms->i_user = U32_AT( p_info );
  250.             break;
  251.         case FOURCC_key:
  252.             if( i_len < sizeof(p_drms->i_key) )
  253.             {
  254.                 i_ret = -1;
  255.                 break;
  256.             }
  257.             p_drms->i_key = U32_AT( p_info );
  258.             break;
  259.         case FOURCC_iviv:
  260.             if( i_len < sizeof(p_drms->p_key) )
  261.             {
  262.                 i_ret = -1;
  263.                 break;
  264.             }
  265.             memcpy( p_drms->p_iviv, p_info, 16 );
  266.             break;
  267.         case FOURCC_name:
  268.             p_drms->p_name = strdup( p_info );
  269.             if( p_drms->p_name == NULL )
  270.             {
  271.                 i_ret = -1;
  272.             }
  273.             break;
  274.         case FOURCC_priv:
  275.         {
  276.             uint32_t p_priv[ 64 ];
  277.             struct md5_s md5;
  278.             if( i_len < 64 )
  279.             {
  280.                 i_ret = -1;
  281.                 break;
  282.             }
  283.             InitMD5( &md5 );
  284.             AddMD5( &md5, p_drms->p_name, strlen( p_drms->p_name ) );
  285.             AddMD5( &md5, p_drms->p_iviv, 16 );
  286.             EndMD5( &md5 );
  287.             if( p_drms->i_user == 0 && p_drms->i_key == 0 )
  288.             {
  289.                 static char const p_secret[] = "tr1-th3n.y00_by3";
  290.                 memcpy( p_drms->p_key, p_secret, 16 );
  291.                 REVERSE( p_drms->p_key, 4 );
  292.             }
  293.             else
  294.             {
  295.                 if( GetUserKey( p_drms, p_drms->p_key ) )
  296.                 {
  297.                     i_ret = -1;
  298.                     break;
  299.                 }
  300.             }
  301.             InitAES( &p_drms->aes, p_drms->p_key );
  302.             memcpy( p_priv, p_info, 64 );
  303.             memcpy( p_drms->p_key, md5.p_digest, 16 );
  304.             drms_decrypt( p_drms, p_priv, 64 );
  305.             REVERSE( p_priv, 64 );
  306.             if( p_priv[ 0 ] != 0x6e757469 ) /* itun */
  307.             {
  308.                 i_ret = -1;
  309.                 break;
  310.             }
  311.             InitAES( &p_drms->aes, p_priv + 6 );
  312.             memcpy( p_drms->p_key, p_priv + 12, 16 );
  313.             free( (void *)p_drms->p_name );
  314.             p_drms->p_name = NULL;
  315.         }
  316.         break;
  317.     }
  318.     return i_ret;
  319. }
  320. /* The following functions are local */
  321. /*****************************************************************************
  322.  * InitAES: initialise AES/Rijndael encryption/decryption tables
  323.  *****************************************************************************
  324.  * The Advanced Encryption Standard (AES) is described in RFC 3268
  325.  *****************************************************************************/
  326. static void InitAES( struct aes_s *p_aes, uint32_t *p_key )
  327. {
  328.     unsigned int i, t;
  329.     uint32_t i_key, i_seed;
  330.     memset( p_aes->pp_enc_keys[1], 0, 16 );
  331.     memcpy( p_aes->pp_enc_keys[0], p_key, 16 );
  332.     /* Generate the key tables */
  333.     i_seed = p_aes->pp_enc_keys[ 0 ][ 3 ];
  334.     for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
  335.     {
  336.         uint32_t j;
  337.         i_seed = AES_ROR( i_seed, 8 );
  338.         j = p_aes_table[ i_key ];
  339.         j ^= p_aes_encrypt[ (i_seed >> 24) & 0xff ]
  340.               ^ AES_ROR( p_aes_encrypt[ (i_seed >> 16) & 0xff ], 8 )
  341.               ^ AES_ROR( p_aes_encrypt[ (i_seed >> 8) & 0xff ], 16 )
  342.               ^ AES_ROR( p_aes_encrypt[ i_seed & 0xff ], 24 );
  343.         j ^= p_aes->pp_enc_keys[ i_key ][ 0 ];
  344.         p_aes->pp_enc_keys[ i_key + 1 ][ 0 ] = j;
  345.         j ^= p_aes->pp_enc_keys[ i_key ][ 1 ];
  346.         p_aes->pp_enc_keys[ i_key + 1 ][ 1 ] = j;
  347.         j ^= p_aes->pp_enc_keys[ i_key ][ 2 ];
  348.         p_aes->pp_enc_keys[ i_key + 1 ][ 2 ] = j;
  349.         j ^= p_aes->pp_enc_keys[ i_key ][ 3 ];
  350.         p_aes->pp_enc_keys[ i_key + 1 ][ 3 ] = j;
  351.         i_seed = j;
  352.     }
  353.     memcpy( p_aes->pp_dec_keys[ 0 ],
  354.             p_aes->pp_enc_keys[ 0 ], 16 );
  355.     for( i = 1; i < AES_KEY_COUNT; i++ )
  356.     {
  357.         for( t = 0; t < 4; t++ )
  358.         {
  359.             uint32_t j, k, l, m, n;
  360.             j = p_aes->pp_enc_keys[ i ][ t ];
  361.             k = (((j >> 7) & 0x01010101) * 27) ^ ((j & 0xff7f7f7f) << 1);
  362.             l = (((k >> 7) & 0x01010101) * 27) ^ ((k & 0xff7f7f7f) << 1);
  363.             m = (((l >> 7) & 0x01010101) * 27) ^ ((l & 0xff7f7f7f) << 1);
  364.             j ^= m;
  365.             n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
  366.             p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
  367.         }
  368.     }
  369. }
  370. /*****************************************************************************
  371.  * DecryptAES: decrypt an AES/Rijndael 128 bit block
  372.  *****************************************************************************/
  373. static void DecryptAES( struct aes_s *p_aes,
  374.                         uint32_t *p_dest, const uint32_t *p_src )
  375. {
  376.     uint32_t p_wtxt[ 4 ]; /* Working cyphertext */
  377.     uint32_t p_tmp[ 4 ];
  378.     unsigned int i_round, t;
  379.     for( t = 0; t < 4; t++ )
  380.     {
  381.         /* FIXME: are there any endianness issues here? */
  382.         p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
  383.     }
  384.     /* Rounds 0 - 8 */
  385.     for( i_round = 0; i_round < (AES_KEY_COUNT - 1); i_round++ )
  386.     {
  387.         for( t = 0; t < 4; t++ )
  388.         {
  389.             p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
  390.         }
  391.         for( t = 0; t < 4; t++ )
  392.         {
  393.             p_wtxt[ t ] = p_tmp[ t ]
  394.                     ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - i_round ][ t ];
  395.         }
  396.     }
  397.     /* Final round (9) */
  398.     for( t = 0; t < 4; t++ )
  399.     {
  400.         p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
  401.         p_dest[ t ] ^= p_aes->pp_dec_keys[ 0 ][ t ];
  402.     }
  403. }
  404. /*****************************************************************************
  405.  * InitMD5: initialise an MD5 message
  406.  *****************************************************************************
  407.  * The MD5 message-digest algorithm is described in RFC 1321
  408.  *****************************************************************************/
  409. static void InitMD5( struct md5_s *p_md5 )
  410. {
  411.     p_md5->p_digest[ 0 ] = 0x67452301;
  412.     p_md5->p_digest[ 1 ] = 0xefcdab89;
  413.     p_md5->p_digest[ 2 ] = 0x98badcfe;
  414.     p_md5->p_digest[ 3 ] = 0x10325476;
  415.     memset( p_md5->p_data, 0, 64 );
  416.     p_md5->i_bits = 0;
  417. }
  418. /*****************************************************************************
  419.  * AddMD5: add i_len bytes to an MD5 message
  420.  *****************************************************************************/
  421. static void AddMD5( struct md5_s *p_md5, const uint8_t *p_src, uint32_t i_len )
  422. {
  423.     unsigned int i_current; /* Current bytes in the spare buffer */
  424.     unsigned int i_offset = 0;
  425.     i_current = (p_md5->i_bits / 8) & 63;
  426.     p_md5->i_bits += 8 * i_len;
  427.     /* If we can complete our spare buffer to 64 bytes, do it and add the
  428.      * resulting buffer to the MD5 message */
  429.     if( i_len >= (64 - i_current) )
  430.     {
  431.         memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src,
  432.                 (64 - i_current) );
  433.         Digest( p_md5, p_md5->p_data );
  434.         i_offset += (64 - i_current);
  435.         i_len -= (64 - i_current);
  436.         i_current = 0;
  437.     }
  438.     /* Add as many entire 64 bytes blocks as we can to the MD5 message */
  439.     while( i_len >= 64 )
  440.     {
  441.         uint32_t p_tmp[ 16 ];
  442.         memcpy( p_tmp, p_src + i_offset, 64 );
  443.         Digest( p_md5, p_tmp );
  444.         i_offset += 64;
  445.         i_len -= 64;
  446.     }
  447.     /* Copy our remaining data to the message's spare buffer */
  448.     memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src + i_offset, i_len );
  449. }
  450. /*****************************************************************************
  451.  * EndMD5: finish an MD5 message
  452.  *****************************************************************************
  453.  * This function adds adequate padding to the end of the message, and appends
  454.  * the bit count so that we end at a block boundary.
  455.  *****************************************************************************/
  456. static void EndMD5( struct md5_s *p_md5 )
  457. {
  458.     unsigned int i_current;
  459.     i_current = (p_md5->i_bits / 8) & 63;
  460.     /* Append 0x80 to our buffer. No boundary check because the temporary
  461.      * buffer cannot be full, otherwise AddMD5 would have emptied it. */
  462.     ((uint8_t *)p_md5->p_data)[ i_current++ ] = 0x80;
  463.     /* If less than 8 bytes are available at the end of the block, complete
  464.      * this 64 bytes block with zeros and add it to the message. We'll add
  465.      * our length at the end of the next block. */
  466.     if( i_current > 56 )
  467.     {
  468.         memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (64 - i_current) );
  469.         Digest( p_md5, p_md5->p_data );
  470.         i_current = 0;
  471.     }
  472.     /* Fill the unused space in our last block with zeroes and put the
  473.      * message length at the end. */
  474.     memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (56 - i_current) );
  475.     p_md5->p_data[ 14 ] = p_md5->i_bits & 0xffffffff;
  476.     p_md5->p_data[ 15 ] = (p_md5->i_bits >> 32);
  477.     REVERSE( &p_md5->p_data[ 14 ], 2 );
  478.     Digest( p_md5, p_md5->p_data );
  479. }
  480. #define F1( x, y, z ) ((z) ^ ((x) & ((y) ^ (z))))
  481. #define F2( x, y, z ) F1((z), (x), (y))
  482. #define F3( x, y, z ) ((x) ^ (y) ^ (z))
  483. #define F4( x, y, z ) ((y) ^ ((x) | ~(z)))
  484. #define MD5_DO( f, w, x, y, z, data, s ) 
  485.     ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
  486. /*****************************************************************************
  487.  * Digest: update the MD5 digest with 64 bytes of data
  488.  *****************************************************************************/
  489. static void Digest( struct md5_s *p_md5, uint32_t *p_input )
  490. {
  491.     uint32_t a, b, c, d;
  492.     REVERSE( p_input, 16 );
  493.     a = p_md5->p_digest[ 0 ];
  494.     b = p_md5->p_digest[ 1 ];
  495.     c = p_md5->p_digest[ 2 ];
  496.     d = p_md5->p_digest[ 3 ];
  497.     MD5_DO( F1, a, b, c, d, p_input[  0 ] + 0xd76aa478,  7 );
  498.     MD5_DO( F1, d, a, b, c, p_input[  1 ] + 0xe8c7b756, 12 );
  499.     MD5_DO( F1, c, d, a, b, p_input[  2 ] + 0x242070db, 17 );
  500.     MD5_DO( F1, b, c, d, a, p_input[  3 ] + 0xc1bdceee, 22 );
  501.     MD5_DO( F1, a, b, c, d, p_input[  4 ] + 0xf57c0faf,  7 );
  502.     MD5_DO( F1, d, a, b, c, p_input[  5 ] + 0x4787c62a, 12 );
  503.     MD5_DO( F1, c, d, a, b, p_input[  6 ] + 0xa8304613, 17 );
  504.     MD5_DO( F1, b, c, d, a, p_input[  7 ] + 0xfd469501, 22 );
  505.     MD5_DO( F1, a, b, c, d, p_input[  8 ] + 0x698098d8,  7 );
  506.     MD5_DO( F1, d, a, b, c, p_input[  9 ] + 0x8b44f7af, 12 );
  507.     MD5_DO( F1, c, d, a, b, p_input[ 10 ] + 0xffff5bb1, 17 );
  508.     MD5_DO( F1, b, c, d, a, p_input[ 11 ] + 0x895cd7be, 22 );
  509.     MD5_DO( F1, a, b, c, d, p_input[ 12 ] + 0x6b901122,  7 );
  510.     MD5_DO( F1, d, a, b, c, p_input[ 13 ] + 0xfd987193, 12 );
  511.     MD5_DO( F1, c, d, a, b, p_input[ 14 ] + 0xa679438e, 17 );
  512.     MD5_DO( F1, b, c, d, a, p_input[ 15 ] + 0x49b40821, 22 );
  513.     MD5_DO( F2, a, b, c, d, p_input[  1 ] + 0xf61e2562,  5 );
  514.     MD5_DO( F2, d, a, b, c, p_input[  6 ] + 0xc040b340,  9 );
  515.     MD5_DO( F2, c, d, a, b, p_input[ 11 ] + 0x265e5a51, 14 );
  516.     MD5_DO( F2, b, c, d, a, p_input[  0 ] + 0xe9b6c7aa, 20 );
  517.     MD5_DO( F2, a, b, c, d, p_input[  5 ] + 0xd62f105d,  5 );
  518.     MD5_DO( F2, d, a, b, c, p_input[ 10 ] + 0x02441453,  9 );
  519.     MD5_DO( F2, c, d, a, b, p_input[ 15 ] + 0xd8a1e681, 14 );
  520.     MD5_DO( F2, b, c, d, a, p_input[  4 ] + 0xe7d3fbc8, 20 );
  521.     MD5_DO( F2, a, b, c, d, p_input[  9 ] + 0x21e1cde6,  5 );
  522.     MD5_DO( F2, d, a, b, c, p_input[ 14 ] + 0xc33707d6,  9 );
  523.     MD5_DO( F2, c, d, a, b, p_input[  3 ] + 0xf4d50d87, 14 );
  524.     MD5_DO( F2, b, c, d, a, p_input[  8 ] + 0x455a14ed, 20 );
  525.     MD5_DO( F2, a, b, c, d, p_input[ 13 ] + 0xa9e3e905,  5 );
  526.     MD5_DO( F2, d, a, b, c, p_input[  2 ] + 0xfcefa3f8,  9 );
  527.     MD5_DO( F2, c, d, a, b, p_input[  7 ] + 0x676f02d9, 14 );
  528.     MD5_DO( F2, b, c, d, a, p_input[ 12 ] + 0x8d2a4c8a, 20 );
  529.     MD5_DO( F3, a, b, c, d, p_input[  5 ] + 0xfffa3942,  4 );
  530.     MD5_DO( F3, d, a, b, c, p_input[  8 ] + 0x8771f681, 11 );
  531.     MD5_DO( F3, c, d, a, b, p_input[ 11 ] + 0x6d9d6122, 16 );
  532.     MD5_DO( F3, b, c, d, a, p_input[ 14 ] + 0xfde5380c, 23 );
  533.     MD5_DO( F3, a, b, c, d, p_input[  1 ] + 0xa4beea44,  4 );
  534.     MD5_DO( F3, d, a, b, c, p_input[  4 ] + 0x4bdecfa9, 11 );
  535.     MD5_DO( F3, c, d, a, b, p_input[  7 ] + 0xf6bb4b60, 16 );
  536.     MD5_DO( F3, b, c, d, a, p_input[ 10 ] + 0xbebfbc70, 23 );
  537.     MD5_DO( F3, a, b, c, d, p_input[ 13 ] + 0x289b7ec6,  4 );
  538.     MD5_DO( F3, d, a, b, c, p_input[  0 ] + 0xeaa127fa, 11 );
  539.     MD5_DO( F3, c, d, a, b, p_input[  3 ] + 0xd4ef3085, 16 );
  540.     MD5_DO( F3, b, c, d, a, p_input[  6 ] + 0x04881d05, 23 );
  541.     MD5_DO( F3, a, b, c, d, p_input[  9 ] + 0xd9d4d039,  4 );
  542.     MD5_DO( F3, d, a, b, c, p_input[ 12 ] + 0xe6db99e5, 11 );
  543.     MD5_DO( F3, c, d, a, b, p_input[ 15 ] + 0x1fa27cf8, 16 );
  544.     MD5_DO( F3, b, c, d, a, p_input[  2 ] + 0xc4ac5665, 23 );
  545.     MD5_DO( F4, a, b, c, d, p_input[  0 ] + 0xf4292244,  6 );
  546.     MD5_DO( F4, d, a, b, c, p_input[  7 ] + 0x432aff97, 10 );
  547.     MD5_DO( F4, c, d, a, b, p_input[ 14 ] + 0xab9423a7, 15 );
  548.     MD5_DO( F4, b, c, d, a, p_input[  5 ] + 0xfc93a039, 21 );
  549.     MD5_DO( F4, a, b, c, d, p_input[ 12 ] + 0x655b59c3,  6 );
  550.     MD5_DO( F4, d, a, b, c, p_input[  3 ] + 0x8f0ccc92, 10 );
  551.     MD5_DO( F4, c, d, a, b, p_input[ 10 ] + 0xffeff47d, 15 );
  552.     MD5_DO( F4, b, c, d, a, p_input[  1 ] + 0x85845dd1, 21 );
  553.     MD5_DO( F4, a, b, c, d, p_input[  8 ] + 0x6fa87e4f,  6 );
  554.     MD5_DO( F4, d, a, b, c, p_input[ 15 ] + 0xfe2ce6e0, 10 );
  555.     MD5_DO( F4, c, d, a, b, p_input[  6 ] + 0xa3014314, 15 );
  556.     MD5_DO( F4, b, c, d, a, p_input[ 13 ] + 0x4e0811a1, 21 );
  557.     MD5_DO( F4, a, b, c, d, p_input[  4 ] + 0xf7537e82,  6 );
  558.     MD5_DO( F4, d, a, b, c, p_input[ 11 ] + 0xbd3af235, 10 );
  559.     MD5_DO( F4, c, d, a, b, p_input[  2 ] + 0x2ad7d2bb, 15 );
  560.     MD5_DO( F4, b, c, d, a, p_input[  9 ] + 0xeb86d391, 21 );
  561.     p_md5->p_digest[ 0 ] += a;
  562.     p_md5->p_digest[ 1 ] += b;
  563.     p_md5->p_digest[ 2 ] += c;
  564.     p_md5->p_digest[ 3 ] += d;
  565. }
  566. /*****************************************************************************
  567.  * InitShuffle: initialise a shuffle structure
  568.  *****************************************************************************
  569.  * This function initialises tables in the p_shuffle structure that will be
  570.  * used later by DoShuffle. The only external parameter is p_sys_key.
  571.  *****************************************************************************/
  572. static void InitShuffle( struct shuffle_s *p_shuffle, uint32_t *p_sys_key,
  573.                          uint32_t i_version )
  574. {
  575.     char p_secret1[] = "Tv!*";
  576.     static char const p_secret2[] = "v8rhvsaAvOKMFfUH%798=[;."
  577.                                     "f8677680a634ba87fnOIf)(*";
  578.     unsigned int i;
  579.     p_shuffle->i_version = i_version;
  580.     /* Fill p_commands using the key and a secret seed */
  581.     for( i = 0; i < 20; i++ )
  582.     {
  583.         struct md5_s md5;
  584.         int32_t i_hash;
  585.         InitMD5( &md5 );
  586.         AddMD5( &md5, (uint8_t *)p_sys_key, 16 );
  587.         AddMD5( &md5, (uint8_t *)p_secret1, 4 );
  588.         EndMD5( &md5 );
  589.         p_secret1[ 3 ]++;
  590.         REVERSE( md5.p_digest, 1 );
  591.         i_hash = ((int32_t)U32_AT(md5.p_digest)) % 1024;
  592.         p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
  593.     }
  594.     /* Fill p_bordel with completely meaningless initial values. */
  595.     for( i = 0; i < 4; i++ )
  596.     {
  597.         p_shuffle->p_bordel[ 4 * i ] = U32_AT(p_sys_key + i);
  598.         memcpy( p_shuffle->p_bordel + 4 * i + 1, p_secret2 + 12 * i, 12 );
  599.         REVERSE( p_shuffle->p_bordel + 4 * i + 1, 3 );
  600.     }
  601. }
  602. /*****************************************************************************
  603.  * DoShuffle: shuffle buffer
  604.  *****************************************************************************
  605.  * This is so ugly and uses so many MD5 checksums that it is most certainly
  606.  * one-way, though why it needs to be so complicated is beyond me.
  607.  *****************************************************************************/
  608. static void DoShuffle( struct shuffle_s *p_shuffle,
  609.                        uint32_t *p_buffer, uint32_t i_size )
  610. {
  611.     struct md5_s md5;
  612.     uint32_t p_big_bordel[ 16 ];
  613.     uint32_t *p_bordel = p_shuffle->p_bordel;
  614.     unsigned int i;
  615.     static uint32_t i_secret = 0;
  616.     static uint32_t p_secret1[] =
  617.     {
  618.         0xAAAAAAAA, 0x01757700, 0x00554580, 0x01724500, 0x00424580,
  619.         0x01427700, 0x00000080, 0xC1D59D01, 0x80144981, 0x815C8901,
  620.         0x80544981, 0x81D45D01, 0x00000080, 0x81A3BB03, 0x00A2AA82,
  621.         0x01A3BB03, 0x0022A282, 0x813BA202, 0x00000080, 0x6D575737,
  622.         0x4A5275A5, 0x6D525725, 0x4A5254A5, 0x6B725437, 0x00000080,
  623.         0xD5DDB938, 0x5455A092, 0x5D95A013, 0x4415A192, 0xC5DD393A,
  624.         0x00000080, 0x55555555
  625.     };
  626.     static char p_secret2[] =
  627.         "pbclevtug (p) Nccyr Pbzchgre, Vap.  Nyy Evtugf Erfreirq.";
  628.     if( i_secret == 0 )
  629.     {
  630.         REVERSE( p_secret1, sizeof(p_secret1)/sizeof(p_secret1[ 0 ]) );
  631.         for( ; p_secret2[ i_secret ] != ''; i_secret++ )
  632.         {
  633. #define ROT13(c) (((c)>='A'&&(c)<='Z')?(((c)-'A'+13)%26)+'A':
  634.                   ((c)>='a'&&(c)<='z')?(((c)-'a'+13)%26)+'a':c)
  635.             p_secret2[ i_secret ] = ROT13(p_secret2[ i_secret ]);
  636.         }
  637.         i_secret++; /* include zero terminator */
  638.     }
  639.     /* Using the MD5 hash of a memory block is probably not one-way enough
  640.      * for the iTunes people. This function randomises p_bordel depending on
  641.      * the values in p_commands to make things even more messy in p_bordel. */
  642.     for( i = 0; i < 20; i++ )
  643.     {
  644.         uint8_t i_command, i_index;
  645.         if( !p_shuffle->p_commands[ i ] )
  646.         {
  647.             continue;
  648.         }
  649.         i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
  650.         i_index = p_shuffle->p_commands[ i ] & 0xff;
  651.         switch( i_command )
  652.         {
  653.         case 0x3:
  654.             p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
  655.                                       + p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
  656.             break;
  657.         case 0x2:
  658.             p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
  659.             break;
  660.         case 0x1:
  661.             p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
  662.             break;
  663.         default:
  664.             p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
  665.             break;
  666.         }
  667.     }
  668.     if( p_shuffle->i_version == 0x01000300 )
  669.     {
  670.         DoExtShuffle( p_bordel );
  671.     }
  672.     /* Convert our newly randomised p_bordel to big endianness and take
  673.      * its MD5 hash. */
  674.     InitMD5( &md5 );
  675.     for( i = 0; i < 16; i++ )
  676.     {
  677.         p_big_bordel[ i ] = U32_AT(p_bordel + i);
  678.     }
  679.     AddMD5( &md5, (uint8_t *)p_big_bordel, 64 );
  680.     if( p_shuffle->i_version == 0x01000300 )
  681.     {
  682.         AddMD5( &md5, (uint8_t *)p_secret1, sizeof(p_secret1) );
  683.         AddMD5( &md5, (uint8_t *)p_secret2, i_secret );
  684.     }
  685.     EndMD5( &md5 );
  686.     /* XOR our buffer with the computed checksum */
  687.     for( i = 0; i < i_size; i++ )
  688.     {
  689.         p_buffer[ i ] ^= md5.p_digest[ i ];
  690.     }
  691. }
  692. /*****************************************************************************
  693.  * DoExtShuffle: extended shuffle
  694.  *****************************************************************************
  695.  * This is even uglier.
  696.  *****************************************************************************/
  697. static void DoExtShuffle( uint32_t * p_bordel )
  698. {
  699.     uint32_t i_ret;
  700.     i_ret = FirstPass( p_bordel );
  701.     SecondPass( p_bordel, i_ret );
  702.     ThirdPass( p_bordel );
  703.     FourthPass( p_bordel );
  704. }
  705. static uint32_t FirstPass( uint32_t * p_bordel )
  706. {
  707.     uint32_t i, i_cmd, i_ret = 5;
  708.     TinyShuffle1( p_bordel );
  709.     for( ; ; )
  710.     {
  711.         for( ; ; )
  712.         {
  713.             p_bordel[ 1 ] += 0x10000000;
  714.             p_bordel[ 3 ] += 0x12777;
  715.             if( (p_bordel[ 10 ] & 1) && i_ret )
  716.             {
  717.                 i_ret--;
  718.                 p_bordel[ 1 ] -= p_bordel[ 2 ];
  719.                 p_bordel[ 11 ] += p_bordel[ 12 ];
  720.                 break;
  721.             }
  722.             if( (p_bordel[ 1 ] + p_bordel[ 2 ]) >= 0x7D0 )
  723.             {
  724.                 switch( ((p_bordel[ 3 ] ^ 0x567F) >> 2) & 7 )
  725.                 {
  726.                     case 0:
  727.                         for( i = 0; i < 3; i++ )
  728.                         {
  729.                             if( p_bordel[ i + 10 ] > 0x4E20 )
  730.                             {
  731.                                 p_bordel[ i + 1 ] += p_bordel[ i + 2 ];
  732.                             }
  733.                         }
  734.                         break;
  735.                     case 4:
  736.                         p_bordel[ 1 ] -= p_bordel[ 2 ];
  737.                         /* no break */
  738.                     case 3:
  739.                         p_bordel[ 11 ] += p_bordel[ 12 ];
  740.                         break;
  741.                     case 6:
  742.                         p_bordel[ 3 ] ^= p_bordel[ 4 ];
  743.                         /* no break */
  744.                     case 8:
  745.                         p_bordel[ 13 ] &= p_bordel[ 14 ];
  746.                         /* no break */
  747.                     case 1:
  748.                         p_bordel[ 0 ] |= p_bordel[ 1 ];
  749.                         if( i_ret )
  750.                         {
  751.                             return i_ret;
  752.                         }
  753.                         break;
  754.                 }
  755.                 break;
  756.             }
  757.         }
  758.         for( i = 0, i_cmd = 0; i < 16; i++ )
  759.         {
  760.             if( p_bordel[ i ] < p_bordel[ i_cmd ] )
  761.             {
  762.                 i_cmd = i;
  763.             }
  764.         }
  765.         if( i_ret && i_cmd != 5 )
  766.         {
  767.             i_ret--;
  768.         }
  769.         else
  770.         {
  771.             if( i_cmd == 5 )
  772.             {
  773.                 p_bordel[ 8 ] &= p_bordel[ 6 ] >> 1;
  774.                 p_bordel[ 3 ] <<= 1;
  775.             }
  776.             for( i = 0; i < 3; i++ )
  777.             {
  778.                 p_bordel[ 11 ] += 1;
  779.                 if( p_bordel[ 11 ] & 5 )
  780.                 {
  781.                     p_bordel[ 8 ] += p_bordel[ 9 ];
  782.                 }
  783.                 else if( i_ret )
  784.                 {
  785.                     i_ret--;
  786.                     i_cmd = 3;
  787.                     goto break2;
  788.                 }
  789.             }
  790.             i_cmd = (p_bordel[ 15 ] + 0x93) >> 3;
  791.             if( p_bordel[ 15 ] & 0x100 )
  792.             {
  793.                 i_cmd ^= 0xDEAD;
  794.             }
  795.         }
  796.         switch( i_cmd & 3 )
  797.         {
  798.             case 0:
  799.                 while( p_bordel[ 11 ] & 1 )
  800.                 {
  801.                     p_bordel[ 11 ] >>= 1;
  802.                     p_bordel[ 12 ] += 1;
  803.                 }
  804.                 /* no break */
  805.             case 2:
  806.                 p_bordel[ 14 ] -= 0x19FE;
  807.                 break;
  808.             case 3:
  809.                 if( i_ret )
  810.                 {
  811.                     i_ret--;
  812.                     p_bordel[ 5 ] += 5;
  813.                     continue;
  814.                 }
  815.                 break;
  816.         }
  817.         i_cmd = ((p_bordel[ 3 ] + p_bordel[ 4 ] + 10) >> 1) - p_bordel[ 4 ];
  818.         break;
  819.     }
  820. break2:
  821.     switch( i_cmd & 3 )
  822.     {
  823.         case 0:
  824.             p_bordel[ 14 ] >>= 1;
  825.             break;
  826.         case 1:
  827.             p_bordel[ 5 ] <<= 2;
  828.             break;
  829.         case 2:
  830.             p_bordel[ 12 ] |= 5;
  831.             break;
  832.         case 3:
  833.             p_bordel[ 15 ] &= 0x55;
  834.             if( i_ret )
  835.             {
  836.                 p_bordel[ 2 ] &= 0xB62FC;
  837.                 return i_ret;
  838.             }
  839.             break;
  840.     }
  841.     TinyShuffle2( p_bordel );
  842.     return i_ret;
  843. }
  844. static void SecondPass( uint32_t * p_bordel, uint32_t i_tmp )
  845. {
  846.     uint32_t i, i_cmd, i_jc = 5;
  847.     TinyShuffle3( p_bordel );
  848.     for( i = 0, i_cmd = 0; i < 16; i++ )
  849.     {
  850.         if( p_bordel[ i ] > p_bordel[ i_cmd ] )
  851.         {
  852.             i_cmd = i;
  853.         }
  854.     }
  855.     switch( i_cmd )
  856.     {
  857.         case 0:
  858.             if( p_bordel[ 1 ] < p_bordel[ 8 ] )
  859.             {
  860.                 p_bordel[ 5 ] += 1;
  861.             }
  862.             break;
  863.         case 4:
  864.             if( (p_bordel[ 9 ] & 0x7777) == 0x3333 )
  865.             {
  866.                 p_bordel[ 5 ] -= 1;
  867.             }
  868.             else
  869.             {
  870.                 i_jc--;
  871.                 if( p_bordel[ 1 ] < p_bordel[ 8 ] )
  872.                 {
  873.                     p_bordel[ 5 ] += 1;
  874.                 }
  875.                 break;
  876.             }
  877.             /* no break */
  878.         case 7:
  879.             p_bordel[ 2 ] -= 1;
  880.             p_bordel[ 1 ] -= p_bordel[ 5 ];
  881.             for( i = 0; i < 3; i++ )
  882.             {
  883.                 switch( p_bordel[ 1 ] & 3 )
  884.                 {
  885.                     case 0:
  886.                         p_bordel[ 1 ] += 1;
  887.                         /* no break */
  888.                     case 1:
  889.                         p_bordel[ 3 ] -= 8;
  890.                         break;
  891.                     case 2:
  892.                         p_bordel[ 13 ] &= 0xFEFEFEF7;
  893.                         break;
  894.                     case 3:
  895.                         p_bordel[ 8 ] |= 0x80080011;
  896.                         break;
  897.                 }
  898.             }
  899.             return;
  900.         case 10:
  901.             p_bordel[ 4 ] -= 1;
  902.             p_bordel[ 5 ] += 1;
  903.             p_bordel[ 6 ] -= 1;
  904.             p_bordel[ 7 ] += 1;
  905.             break;
  906.         default:
  907.             p_bordel[ 15 ] ^= 0x18547EFF;
  908.             break;
  909.     }
  910.     for( i = 3; i--; )
  911.     {
  912.         switch( ( p_bordel[ 12 ] + p_bordel[ 13 ] + p_bordel[ 6 ] ) % 5 )
  913.         {
  914.             case 0:
  915.                 p_bordel[ 12 ] -= 1;
  916.                 /* no break */
  917.             case 1:
  918.                 p_bordel[ 12 ] -= 1;
  919.                 p_bordel[ 13 ] += 1;
  920.                 break;
  921.             case 2:
  922.                 p_bordel[ 13 ] += 4;
  923.                 /* no break */
  924.             case 3:
  925.                 p_bordel[ 12 ] -= 1;
  926.                 break;
  927.             case 4:
  928.                 i_jc--;
  929.                 p_bordel[ 5 ] += 1;
  930.                 p_bordel[ 6 ] -= 1;
  931.                 p_bordel[ 7 ] += 1;
  932.                 i = 3; /* Restart the whole loop */
  933.                 break;
  934.         }
  935.     }
  936.     TinyShuffle4( p_bordel );
  937.     for( ; ; )
  938.     {
  939.         TinyShuffle5( p_bordel );
  940.         switch( ( p_bordel[ 2 ] * 2 + 15 ) % 5 )
  941.         {
  942.             case 0:
  943.                 if( ( p_bordel[ 3 ] + i_tmp ) <=
  944.                     ( p_bordel[ 1 ] + p_bordel[ 15 ] ) )
  945.                 {
  946.                     p_bordel[ 3 ] += 1;
  947.                 }
  948.                 break;
  949.             case 4:
  950.                 p_bordel[ 10 ] -= 0x13;
  951.                 break;
  952.             case 3:
  953.                 p_bordel[ 5 ] >>= 2;
  954.                 break;
  955.         }
  956.         if( !( p_bordel[ 2 ] & 1 ) || i_jc == 0 )
  957.         {
  958.             break;
  959.         }
  960.         i_jc--;
  961.         p_bordel[ 2 ] += 0x13;
  962.         p_bordel[ 12 ] += 1;
  963.     }
  964.     p_bordel[ 2 ] &= 0x10076000;
  965. }
  966. static void ThirdPass( uint32_t * p_bordel )
  967. {
  968.     uint32_t i_cmd;
  969.     i_cmd = ((p_bordel[ 7 ] + p_bordel[ 14 ] + 10) >> 1) - p_bordel[ 14 ];
  970.     i_cmd = i_cmd % 10;
  971.     switch( i_cmd )
  972.     {
  973.         case 0:
  974.             p_bordel[ 1 ] <<= 1;
  975.             p_bordel[ 2 ] <<= 2;
  976.             p_bordel[ 3 ] <<= 3;
  977.             break;
  978.         case 6:
  979.             p_bordel[ i_cmd + 3 ] &= 0x5EDE36B;
  980.             p_bordel[ 5 ] += p_bordel[ 8 ];
  981.             p_bordel[ 4 ] += p_bordel[ 7 ];
  982.             p_bordel[ 3 ] += p_bordel[ 6 ];
  983.             p_bordel[ 2 ] += p_bordel[ 5 ];
  984.             /* no break */
  985.         case 2:
  986.             p_bordel[ 1 ] += p_bordel[ 4 ];
  987.             p_bordel[ 0 ] += p_bordel[ 3 ];
  988.             TinyShuffle6( p_bordel );
  989.             return; /* jc = 4 */
  990.         case 3:
  991.             if( (p_bordel[ 11 ] & p_bordel[ 2 ]) > 0x211B )
  992.             {
  993.                 p_bordel[ 6 ] += 1;
  994.             }
  995.             break;
  996.         case 4:
  997.             p_bordel[ 7 ] += 1;
  998.             /* no break */
  999.         case 5:
  1000.             p_bordel[ 9 ] ^= p_bordel[ 2 ];
  1001.             break;
  1002.         case 7:
  1003.             p_bordel[ 2 ] ^= (p_bordel[ 1 ] & p_bordel[ 13 ]);
  1004.             break;
  1005.         case 8:
  1006.             p_bordel[ 0 ] -= p_bordel[ 11 ] & p_bordel[ 15 ];
  1007.             return; /* jc = 4 */
  1008.         case 9:
  1009.             p_bordel[ 6 ] >>= (p_bordel[ 14 ] & 3);
  1010.             break;
  1011.     }
  1012.     SWAP( p_bordel[ 0 ], p_bordel[ 10 ] );
  1013.     TinyShuffle6( p_bordel );
  1014.     return; /* jc = 5 */
  1015. }
  1016. static void FourthPass( uint32_t * p_bordel )
  1017. {
  1018.     uint32_t i, j;
  1019.     TinyShuffle7( p_bordel );
  1020.     switch( p_bordel[ 5 ] % 5)
  1021.     {
  1022.         case 0:
  1023.             p_bordel[ 0 ] += 1;
  1024.             break;
  1025.         case 2:
  1026.             p_bordel[ 11 ] ^= (p_bordel[ 3 ] + p_bordel[ 6 ] + p_bordel[ 8 ]);
  1027.             break;
  1028.         case 3:
  1029.             for( i = 4; i < 15 && (p_bordel[ i ] & 5) == 0; i++ )
  1030.             {
  1031.                 SWAP( p_bordel[ i ], p_bordel[ 15 - i ] );
  1032.             }
  1033.             break;
  1034.         case 4:
  1035.             p_bordel[ 12 ] -= 1;
  1036.             p_bordel[ 13 ] += 1;
  1037.             p_bordel[ 2 ] -= 0x64;
  1038.             p_bordel[ 3 ] += 0x64;
  1039.             TinyShuffle8( p_bordel );
  1040.             return;
  1041.     }
  1042.     for( i = 0, j = 0; i < 16; i++ )
  1043.     {
  1044.         if( p_bordel[ i ] > p_bordel[ j ] )
  1045.         {
  1046.             j = i;
  1047.         }
  1048.     }
  1049.     switch( p_bordel[ j ] % 100 )
  1050.     {
  1051.         case 0:
  1052.             SWAP( p_bordel[ 0 ], p_bordel[ j ] );
  1053.             break;
  1054.         case 8:
  1055.             p_bordel[ 1 ] >>= 1;
  1056.             p_bordel[ 2 ] <<= 1;
  1057.             p_bordel[ 14 ] >>= 3;
  1058.             p_bordel[ 15 ] <<= 4;
  1059.             break;
  1060.         case 57:
  1061.             p_bordel[ j ] += p_bordel[ 13 ];
  1062.             break;
  1063.         case 76:
  1064.             p_bordel[ 1 ] += 0x20E;
  1065.             p_bordel[ 5 ] += 0x223D;
  1066.             p_bordel[ 13 ] -= 0x576;
  1067.             p_bordel[ 15 ] += 0x576;
  1068.             return;
  1069.         case 91:
  1070.             p_bordel[ 2 ] -= 0x64;
  1071.             p_bordel[ 3 ] += 0x64;
  1072.             p_bordel[ 12 ] -= 1;
  1073.             p_bordel[ 13 ] += 1;
  1074.             break;
  1075.         case 99:
  1076.             p_bordel[ 0 ] += 1;
  1077.             p_bordel[ j ] += p_bordel[ 13 ];
  1078.             break;
  1079.     }
  1080.     TinyShuffle8( p_bordel );
  1081. }
  1082. /*****************************************************************************
  1083.  * TinyShuffle[12345678]: tiny shuffle subroutines
  1084.  *****************************************************************************
  1085.  * These standalone functions are little helpers for the shuffling process.
  1086.  *****************************************************************************/
  1087. static void TinyShuffle1( uint32_t * p_bordel )
  1088. {
  1089.     uint32_t i_cmd = (p_bordel[ 5 ] + 10) >> 2;
  1090.     if( p_bordel[ 5 ] > 0x7D0 )
  1091.     {
  1092.         i_cmd -= 0x305;
  1093.     }
  1094.     switch( i_cmd & 3 )
  1095.     {
  1096.         case 0:
  1097.             p_bordel[ 5 ] += 5;
  1098.             break;
  1099.         case 1:
  1100.             p_bordel[ 4 ] -= 1;
  1101.             break;
  1102.         case 2:
  1103.             if( p_bordel[ 4 ] & 5 )
  1104.             {
  1105.                 p_bordel[ 1 ] ^= 0x4D;
  1106.             }
  1107.             /* no break */
  1108.         case 3:
  1109.             p_bordel[ 12 ] += 5;
  1110.             break;
  1111.     }
  1112. }
  1113. static void TinyShuffle2( uint32_t * p_bordel )
  1114. {
  1115.     uint32_t i, j;
  1116.     for( i = 0, j = 0; i < 16; i++ )
  1117.     {
  1118.         if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) )
  1119.         {
  1120.             j = i;
  1121.         }
  1122.     }
  1123.     if( j > 5 )
  1124.     {
  1125.         for( ; j < 15; j++ )
  1126.         {
  1127.             p_bordel[ j ] += p_bordel[ j + 1 ];
  1128.         }
  1129.     }
  1130.     else
  1131.     {
  1132.         p_bordel[ 2 ] &= 0xB62FC;
  1133.     }
  1134. }
  1135. static void TinyShuffle3( uint32_t * p_bordel )
  1136. {
  1137.     uint32_t i_cmd = p_bordel[ 6 ] + 0x194B;
  1138.     if( p_bordel[ 6 ] > 0x2710 )
  1139.     {
  1140.         i_cmd >>= 1;
  1141.     }
  1142.     switch( i_cmd & 3 )
  1143.     {
  1144.         case 1:
  1145.             p_bordel[ 3 ] += 0x19FE;
  1146.             break;
  1147.         case 2:
  1148.             p_bordel[ 7 ] -= p_bordel[ 3 ] >> 2;
  1149.             /* no break */
  1150.         case 0:
  1151.             p_bordel[ 5 ] ^= 0x248A;
  1152.             break;
  1153.     }
  1154. }
  1155. static void TinyShuffle4( uint32_t * p_bordel )
  1156. {
  1157.     uint32_t i, j;
  1158.     for( i = 0, j = 0; i < 16; i++ )
  1159.     {
  1160.         if( p_bordel[ i ] < p_bordel[ j ] )
  1161.         {
  1162.             j = i;
  1163.         }
  1164.     }
  1165.     if( (p_bordel[ j ] % (j + 1)) > 10 )
  1166.     {
  1167.         p_bordel[ 1 ] -= 1;
  1168.         p_bordel[ 2 ] += 0x13;
  1169.         p_bordel[ 12 ] += 1;
  1170.     }
  1171. }
  1172. static void TinyShuffle5( uint32_t * p_bordel )
  1173. {
  1174.     uint32_t i;
  1175.     p_bordel[ 2 ] &= 0x7F3F;
  1176.     for( i = 0; i < 5; i++ )
  1177.     {
  1178.         switch( ( p_bordel[ 2 ] + 10 + i ) % 5 )
  1179.         {
  1180.             case 0:
  1181.                 p_bordel[ 12 ] &= p_bordel[ 2 ];
  1182.                 /* no break */
  1183.             case 1:
  1184.                 p_bordel[ 3 ] ^= p_bordel[ 15 ];
  1185.                 break;
  1186.             case 2:
  1187.                 p_bordel[ 15 ] += 0x576;
  1188.                 /* no break */
  1189.             case 3:
  1190.                 p_bordel[ 7 ] -= 0x2D;
  1191.                 /* no break */
  1192.             case 4:
  1193.                 p_bordel[ 1 ] <<= 1;
  1194.                 break;
  1195.         }
  1196.     }
  1197. }
  1198. static void TinyShuffle6( uint32_t * p_bordel )
  1199. {
  1200.     uint32_t i, j;
  1201.     for( i = 0; i < 8; i++ )
  1202.     {
  1203.         j = p_bordel[ 3 ] & 0x7514 ? 5 : 7;
  1204.         SWAP( p_bordel[ i ], p_bordel[ i + j ] );
  1205.     }
  1206. }
  1207. static void TinyShuffle7( uint32_t * p_bordel )
  1208. {
  1209.     uint32_t i;
  1210.     i = (((p_bordel[ 9 ] + p_bordel[ 15 ] + 12) >> 2) - p_bordel[ 4 ]) & 7;
  1211.     while( i-- )
  1212.     {
  1213.         SWAP( p_bordel[ i ], p_bordel[ i + 3 ] );
  1214.     }
  1215.     SWAP( p_bordel[ 1 ], p_bordel[ 10 ] );
  1216. }
  1217. static void TinyShuffle8( uint32_t * p_bordel )
  1218. {
  1219.     uint32_t i;
  1220.     i = (p_bordel[ 0 ] & p_bordel[ 6 ]) & 0xF;
  1221.     switch( p_bordel[ i ] % 1000 )
  1222.     {
  1223.         case 7:
  1224.             if( (p_bordel[ i ] & 0x777) > (p_bordel[ 7 ] & 0x5555) )
  1225.             {
  1226.                 p_bordel[ i ] ^= p_bordel[ 5 ] & p_bordel[ 3 ];
  1227.             }
  1228.             break;
  1229.         case 19:
  1230.             p_bordel[ 15 ] &= 0x5555;
  1231.             break;
  1232.         case 93:
  1233.             p_bordel[ i ] ^= p_bordel[ 15 ];
  1234.             break;
  1235.         case 100:
  1236.             SWAP( p_bordel[ 0 ], p_bordel[ 3 ] );
  1237.             SWAP( p_bordel[ 1 ], p_bordel[ 6 ] );
  1238.             SWAP( p_bordel[ 3 ], p_bordel[ 6 ] );
  1239.             SWAP( p_bordel[ 4 ], p_bordel[ 9 ] );
  1240.             SWAP( p_bordel[ 5 ], p_bordel[ 8 ] );
  1241.             SWAP( p_bordel[ 6 ], p_bordel[ 7 ] );
  1242.             SWAP( p_bordel[ 13 ], p_bordel[ 14 ] );
  1243.             break;
  1244.         case 329:
  1245.             p_bordel[ i ] += p_bordel[ 1 ] ^ 0x80080011;
  1246.             p_bordel[ i ] += p_bordel[ 2 ] ^ 0xBEEFDEAD;
  1247.             p_bordel[ i ] += p_bordel[ 3 ] ^ 0x8765F444;
  1248.             p_bordel[ i ] += p_bordel[ 4 ] ^ 0x78145326;
  1249.             break;
  1250.         case 567:
  1251.             p_bordel[ 12 ] -= p_bordel[ i ];
  1252.             p_bordel[ 13 ] += p_bordel[ i ];
  1253.             break;
  1254.         case 612:
  1255.             p_bordel[ i ] += p_bordel[ 1 ];
  1256.             p_bordel[ i ] -= p_bordel[ 7 ];
  1257.             p_bordel[ i ] -= p_bordel[ 8 ];
  1258.             p_bordel[ i ] += p_bordel[ 9 ];
  1259.             p_bordel[ i ] += p_bordel[ 13 ];
  1260.             break;
  1261.         case 754:
  1262.             i = __MIN( i, 12 );
  1263.             p_bordel[ i + 1 ] >>= 1;
  1264.             p_bordel[ i + 2 ] <<= 4;
  1265.             p_bordel[ i + 3 ] >>= 3;
  1266.             break;
  1267.         case 777:
  1268.             p_bordel[ 1 ] += 0x20E;
  1269.             p_bordel[ 5 ] += 0x223D;
  1270.             p_bordel[ 13 ] -= 0x576;
  1271.             p_bordel[ 15 ] += 0x576;
  1272.             break;
  1273.         case 981:
  1274.             if( (p_bordel[ i ] ^ 0x8765F441) < 0x2710 )
  1275.             {
  1276.                 SWAP( p_bordel[ 0 ], p_bordel[ 1 ] );
  1277.             }
  1278.             else
  1279.             {
  1280.                 SWAP( p_bordel[ 1 ], p_bordel[ 11 ] );
  1281.             }
  1282.             break;
  1283.     }
  1284. }
  1285. /*****************************************************************************
  1286.  * GetSystemKey: get the system key
  1287.  *****************************************************************************
  1288.  * Compute the system key from various system information, see HashSystemInfo.
  1289.  *****************************************************************************/
  1290. static int GetSystemKey( uint32_t *p_sys_key, vlc_bool_t b_ipod )
  1291. {
  1292.     static char const p_secret1[ 8 ] = "YuaFlafu";
  1293.     static char const p_secret2[ 8 ] = "zPif98ga";
  1294.     struct md5_s md5;
  1295.     int64_t i_ipod_id;
  1296.     uint32_t p_system_hash[ 4 ];
  1297.     /* Compute the MD5 hash of our system info */
  1298.     if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) ||
  1299.         (  b_ipod && GetiPodID( &i_ipod_id ) ) )
  1300.     {
  1301.         return -1;
  1302.     }
  1303.     /* Combine our system info hash with additional secret data. The resulting
  1304.      * MD5 hash will be our system key. */
  1305.     InitMD5( &md5 );
  1306.     AddMD5( &md5, p_secret1, 8 );
  1307.     if( !b_ipod )
  1308.     {
  1309.         AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
  1310.         AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
  1311.         AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
  1312.         AddMD5( &md5, p_secret2, 8 );
  1313.     }
  1314.     else
  1315.     {
  1316.         i_ipod_id = U64_AT(&i_ipod_id);
  1317.         AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
  1318.         AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
  1319.         AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
  1320.     }
  1321.     EndMD5( &md5 );
  1322.     memcpy( p_sys_key, md5.p_digest, 16 );
  1323.     return 0;
  1324. }
  1325. #ifdef WIN32
  1326. #   define DRMS_DIRNAME "drms"
  1327. #else
  1328. #   define DRMS_DIRNAME ".drms"
  1329. #endif
  1330. /*****************************************************************************
  1331.  * WriteUserKey: write the user key to hard disk
  1332.  *****************************************************************************
  1333.  * Write the user key to the hard disk so that it can be reused later or used
  1334.  * on operating systems other than Win32.
  1335.  *****************************************************************************/
  1336. static int WriteUserKey( void *_p_drms, uint32_t *p_user_key )
  1337. {
  1338.     struct drms_s *p_drms = (struct drms_s *)_p_drms;
  1339.     FILE *file;
  1340.     int i_ret = -1;
  1341.     char psz_path[ PATH_MAX ];
  1342.     snprintf( psz_path, PATH_MAX - 1,
  1343.               "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
  1344. #if defined( HAVE_ERRNO_H )
  1345. #   if defined( WIN32 )
  1346.     if( !mkdir( psz_path ) || errno == EEXIST )
  1347. #   else
  1348.     if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
  1349. #   endif
  1350. #else
  1351.     if( !mkdir( psz_path ) )
  1352. #endif
  1353.     {
  1354.         snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d",
  1355.                   p_drms->psz_homedir, p_drms->i_user, p_drms->i_key );
  1356.         file = fopen( psz_path, "wb" );
  1357.         if( file != NULL )
  1358.         {
  1359.             i_ret = fwrite( p_user_key, sizeof(uint32_t),
  1360.                             4, file ) == 4 ? 0 : -1;
  1361.             fclose( file );
  1362.         }
  1363.     }
  1364.     return i_ret;
  1365. }
  1366. /*****************************************************************************
  1367.  * ReadUserKey: read the user key from hard disk
  1368.  *****************************************************************************
  1369.  * Retrieve the user key from the hard disk if available.
  1370.  *****************************************************************************/
  1371. static int ReadUserKey( void *_p_drms, uint32_t *p_user_key )
  1372. {
  1373.     struct drms_s *p_drms = (struct drms_s *)_p_drms;
  1374.     FILE *file;
  1375.     int i_ret = -1;
  1376.     char psz_path[ PATH_MAX ];
  1377.     snprintf( psz_path, PATH_MAX - 1,
  1378.               "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir,
  1379.               p_drms->i_user, p_drms->i_key );
  1380.     file = fopen( psz_path, "rb" );
  1381.     if( file != NULL )
  1382.     {
  1383.         i_ret = fread( p_user_key, sizeof(uint32_t),
  1384.                        4, file ) == 4 ? 0 : -1;
  1385.         fclose( file );
  1386.     }
  1387.     return i_ret;
  1388. }
  1389. /*****************************************************************************
  1390.  * GetUserKey: get the user key
  1391.  *****************************************************************************
  1392.  * Retrieve the user key from the hard disk if available, otherwise generate
  1393.  * it from the system key. If the key could be successfully generated, write
  1394.  * it to the hard disk for future use.
  1395.  *****************************************************************************/
  1396. static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
  1397. {
  1398.     static char const p_secret[] = "mUfnpognadfgf873";
  1399.     struct drms_s *p_drms = (struct drms_s *)_p_drms;
  1400.     struct aes_s aes;
  1401.     struct shuffle_s shuffle;
  1402.     uint32_t i, y;
  1403.     uint32_t *p_sci_data;
  1404.     uint32_t i_user, i_key;
  1405.     uint32_t p_sys_key[ 4 ];
  1406.     uint32_t i_sci_size, i_blocks, i_remaining;
  1407.     uint32_t *p_sci0, *p_sci1, *p_buffer;
  1408.     uint32_t p_sci_key[ 4 ];
  1409.     char *psz_ipod;
  1410.     int i_ret = -1;
  1411.     if( !ReadUserKey( p_drms, p_user_key ) )
  1412.     {
  1413.         REVERSE( p_user_key, 4 );
  1414.         return 0;
  1415.     }
  1416.     psz_ipod = getenv( "IPOD" );
  1417.     if( GetSystemKey( p_sys_key, psz_ipod ? VLC_TRUE : VLC_FALSE ) )
  1418.     {
  1419.         return -1;
  1420.     }
  1421.     if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
  1422.     {
  1423.         return -1;
  1424.     }
  1425.     /* Phase 1: unscramble the SCI data using the system key and shuffle
  1426.      *          it using DoShuffle(). */
  1427.     /* Skip the first 4 bytes (some sort of header). Decrypt the rest. */
  1428.     i_blocks = (i_sci_size - 4) / 16;
  1429.     i_remaining = (i_sci_size - 4) - (i_blocks * 16);
  1430.     p_buffer = p_sci_data + 1;
  1431.     /* Decrypt and shuffle our data at the same time */
  1432.     InitAES( &aes, p_sys_key );
  1433.     REVERSE( p_sys_key, 4 );
  1434.     REVERSE( p_sci_data, 1 );
  1435.     InitShuffle( &shuffle, p_sys_key, p_sci_data[ 0 ] );
  1436.     memcpy( p_sci_key, p_secret, 16 );
  1437.     REVERSE( p_sci_key, 4 );
  1438.     while( i_blocks-- )
  1439.     {
  1440.         uint32_t p_tmp[ 4 ];
  1441.         REVERSE( p_buffer, 4 );
  1442.         DecryptAES( &aes, p_tmp, p_buffer );
  1443.         BlockXOR( p_tmp, p_sci_key, p_tmp );
  1444.         /* Use the previous scrambled data as the key for next block */
  1445.         memcpy( p_sci_key, p_buffer, 16 );
  1446.         /* Shuffle the decrypted data using a custom routine */
  1447.         DoShuffle( &shuffle, p_tmp, 4 );
  1448.         /* Copy this block back to p_buffer */
  1449.         memcpy( p_buffer, p_tmp, 16 );
  1450.         p_buffer += 4;
  1451.     }
  1452.     if( i_remaining >= 4 )
  1453.     {
  1454.         i_remaining /= 4;
  1455.         REVERSE( p_buffer, i_remaining );
  1456.         DoShuffle( &shuffle, p_buffer, i_remaining );
  1457.     }
  1458.     /* Phase 2: look for the user key in the generated data. I must admit I
  1459.      *          do not understand what is going on here, because it almost
  1460.      *          looks like we are browsing data that makes sense, even though
  1461.      *          the DoShuffle() part made it completely meaningless. */
  1462.     y = 0;
  1463.     REVERSE( p_sci_data + 5, 1 );
  1464.     i = U32_AT( p_sci_data + 5 );
  1465.     i_sci_size -= 22 * sizeof(uint32_t);
  1466.     p_sci1 = p_sci_data + 22;
  1467.     p_sci0 = NULL;
  1468.     while( i_sci_size >= 20 && i > 0 )
  1469.     {
  1470.         if( p_sci0 == NULL )
  1471.         {
  1472.             i_sci_size -= 18 * sizeof(uint32_t);
  1473.             if( i_sci_size < 20 )
  1474.             {
  1475.                 break;
  1476.             }
  1477.             p_sci0 = p_sci1;
  1478.             REVERSE( p_sci1 + 17, 1 );
  1479.             y = U32_AT( p_sci1 + 17 );
  1480.             p_sci1 += 18;
  1481.         }
  1482.         if( !y )
  1483.         {
  1484.             i--;
  1485.             p_sci0 = NULL;
  1486.             continue;
  1487.         }
  1488.         i_user = U32_AT( p_sci0 );
  1489.         i_key = U32_AT( p_sci1 );
  1490.         REVERSE( &i_user, 1 );
  1491.         REVERSE( &i_key, 1 );
  1492.         if( i_user == p_drms->i_user && ( ( i_key == p_drms->i_key ) ||
  1493.             ( !p_drms->i_key && ( p_sci1 == (p_sci0 + 18) ) ) ) )
  1494.         {
  1495.             memcpy( p_user_key, p_sci1 + 1, 16 );
  1496.             REVERSE( p_sci1 + 1, 4 );
  1497.             WriteUserKey( p_drms, p_sci1 + 1 );
  1498.             i_ret = 0;
  1499.             break;
  1500.         }
  1501.         y--;
  1502.         p_sci1 += 5;
  1503.         i_sci_size -= 5 * sizeof(uint32_t);
  1504.     }
  1505.     free( p_sci_data );
  1506.     return i_ret;
  1507. }
  1508. /*****************************************************************************
  1509.  * GetSCIData: get SCI data from "SC Info.sidb"
  1510.  *****************************************************************************
  1511.  * Read SCI data from "Apple ComputeriTunesSC InfoSC Info.sidb"
  1512.  *****************************************************************************/
  1513. static int GetSCIData( char *psz_ipod, uint32_t **pp_sci,
  1514.                        uint32_t *pi_sci_size )
  1515. {
  1516.     FILE *file;
  1517.     char *psz_path = NULL;
  1518.     char p_tmp[ PATH_MAX ];
  1519.     int i_ret = -1;
  1520.     if( psz_ipod == NULL )
  1521.     {
  1522. #ifdef WIN32
  1523.         char *p_filename = "\Apple Computer\iTunes\SC Info\SC Info.sidb";
  1524.         typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
  1525.                                                    LPSTR );
  1526.         HINSTANCE shfolder_dll = NULL;
  1527.         SHGETFOLDERPATH dSHGetFolderPath = NULL;
  1528.         if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
  1529.         {
  1530.             dSHGetFolderPath =
  1531.                 (SHGETFOLDERPATH)GetProcAddress( shfolder_dll,
  1532.                                                  _T("SHGetFolderPathA") );
  1533.         }
  1534.         if( dSHGetFolderPath != NULL &&
  1535.             SUCCEEDED( dSHGetFolderPath( NULL, CSIDL_COMMON_APPDATA,
  1536.                                          NULL, 0, p_tmp ) ) )
  1537.         {
  1538.             strncat( p_tmp, p_filename, min( strlen( p_filename ),
  1539.                      (sizeof(p_tmp)/sizeof(p_tmp[0]) - 1) -
  1540.                      strlen( p_tmp ) ) );
  1541.             psz_path = p_tmp;
  1542.         }
  1543.         if( shfolder_dll != NULL )
  1544.         {
  1545.             FreeLibrary( shfolder_dll );
  1546.         }
  1547. #endif
  1548.     }
  1549.     else
  1550.     {
  1551. #define ISCINFO "iSCInfo"
  1552.         if( strstr( psz_ipod, ISCINFO ) == NULL )
  1553.         {
  1554.             snprintf( p_tmp, sizeof(p_tmp)/sizeof(p_tmp[0]) - 1,
  1555.                       "%s/iPod_Control/iTunes/" ISCINFO "2", psz_ipod );
  1556.             psz_path = p_tmp;
  1557.         }
  1558.         else
  1559.         {
  1560.             psz_path = psz_ipod;
  1561.         }
  1562.     }
  1563.     if( psz_path == NULL )
  1564.     {
  1565.         return -1;
  1566.     }
  1567.     file = fopen( psz_path, "rb" );
  1568.     if( file != NULL )
  1569.     {
  1570.         struct stat st;
  1571.         if( !fstat( fileno( file ), &st ) && st.st_size >= 4 )
  1572.         {
  1573.             *pp_sci = malloc( st.st_size );
  1574.             if( *pp_sci != NULL )
  1575.             {
  1576.                 if( fread( *pp_sci, 1, st.st_size,
  1577.                            file ) == (size_t)st.st_size )
  1578.                 {
  1579.                     *pi_sci_size = st.st_size;
  1580.                     i_ret = 0;
  1581.                 }
  1582.                 else
  1583.                 {
  1584.                     free( (void *)*pp_sci );
  1585.                     *pp_sci = NULL;
  1586.                 }
  1587.             }
  1588.         }
  1589.         fclose( file );
  1590.     }
  1591.     return i_ret;
  1592. }
  1593. /*****************************************************************************
  1594.  * HashSystemInfo: hash system information
  1595.  *****************************************************************************
  1596.  * This function computes the MD5 hash of the C: hard drive serial number,
  1597.  * BIOS version, CPU type and Windows version.
  1598.  *****************************************************************************/
  1599. static int HashSystemInfo( uint32_t *p_system_hash )
  1600. {
  1601.     struct md5_s md5;
  1602.     int i_ret = 0;
  1603. #ifdef WIN32
  1604.     HKEY i_key;
  1605.     unsigned int i;
  1606.     DWORD i_size;
  1607.     DWORD i_serial;
  1608.     LPBYTE p_reg_buf;
  1609.     static LPCTSTR p_reg_keys[ 3 ][ 2 ] =
  1610.     {
  1611.         {
  1612.             _T("HARDWARE\DESCRIPTION\System"),
  1613.             _T("SystemBiosVersion")
  1614.         },
  1615.         {
  1616.             _T("HARDWARE\DESCRIPTION\System\CentralProcessor\0"),
  1617.             _T("ProcessorNameString")
  1618.         },
  1619.         {
  1620.             _T("SOFTWARE\Microsoft\Windows\CurrentVersion"),
  1621.             _T("ProductId")
  1622.         }
  1623.     };
  1624.     InitMD5( &md5 );
  1625.     AddMD5( &md5, "cache-control", 13 );
  1626.     AddMD5( &md5, "Ethernet", 8 );
  1627.     GetVolumeInformation( _T("C:\"), NULL, 0, &i_serial,
  1628.                           NULL, NULL, NULL, 0 );
  1629.     AddMD5( &md5, (uint8_t *)&i_serial, 4 );
  1630.     for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
  1631.     {
  1632.         if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
  1633.                           0, KEY_READ, &i_key ) != ERROR_SUCCESS )
  1634.         {
  1635.             continue;
  1636.         }
  1637.         if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
  1638.                              NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
  1639.         {
  1640.             RegCloseKey( i_key );
  1641.             continue;
  1642.         }
  1643.         p_reg_buf = malloc( i_size );
  1644.         if( p_reg_buf != NULL )
  1645.         {
  1646.             if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
  1647.                                  NULL, NULL, p_reg_buf,
  1648.                                  &i_size ) == ERROR_SUCCESS )
  1649.             {
  1650.                 AddMD5( &md5, (uint8_t *)p_reg_buf, i_size );
  1651.             }
  1652.             free( p_reg_buf );
  1653.         }
  1654.         RegCloseKey( i_key );
  1655.     }
  1656. #else
  1657.     InitMD5( &md5 );
  1658.     i_ret = -1;
  1659. #endif
  1660.     EndMD5( &md5 );
  1661.     memcpy( p_system_hash, md5.p_digest, 16 );
  1662.     return i_ret;
  1663. }
  1664. /*****************************************************************************
  1665.  * GetiPodID: Get iPod ID
  1666.  *****************************************************************************
  1667.  * This function gets the iPod ID.
  1668.  *****************************************************************************/
  1669. static int GetiPodID( int64_t *p_ipod_id )
  1670. {
  1671.     int i_ret = -1;
  1672. #define PROD_NAME   "iPod"
  1673. #define VENDOR_NAME "Apple Computer, Inc."
  1674.     char *psz_ipod_id = getenv( "IPODID" );
  1675.     if( psz_ipod_id != NULL )
  1676.     {
  1677.         *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
  1678.         return 0;
  1679.     }
  1680. #ifdef SYS_DARWIN
  1681.     CFTypeRef value;
  1682.     mach_port_t port;
  1683.     io_object_t device;
  1684.     io_iterator_t iterator;
  1685.     CFMutableDictionaryRef match_dic;
  1686.     CFMutableDictionaryRef smatch_dic;
  1687.     if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
  1688.     {
  1689.         smatch_dic = IOServiceMatching( "IOFireWireUnit" );
  1690.         match_dic = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
  1691.                                            &kCFTypeDictionaryKeyCallBacks,
  1692.                                            &kCFTypeDictionaryValueCallBacks );
  1693.         if( smatch_dic != NULL && match_dic != NULL )
  1694.         {
  1695.             CFDictionarySetValue( smatch_dic,
  1696.                                   CFSTR("FireWire Vendor Name"),
  1697.                                   CFSTR(VENDOR_NAME) );
  1698.             CFDictionarySetValue( smatch_dic,
  1699.                                   CFSTR("FireWire Product Name"),
  1700.                                   CFSTR(PROD_NAME) );
  1701.             CFDictionarySetValue( match_dic,
  1702.                                   CFSTR(kIOPropertyMatchKey),
  1703.                                   smatch_dic );
  1704.             if( IOServiceGetMatchingServices( port, match_dic,
  1705.                                               &iterator ) == KERN_SUCCESS )
  1706.             {
  1707.                 while( ( device = IOIteratorNext( iterator ) ) != NULL )
  1708.                 {
  1709.                     value = IORegistryEntryCreateCFProperty( device,
  1710.                         CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );
  1711.                     if( value != NULL )
  1712.                     {
  1713.                         if( CFGetTypeID( value ) == CFNumberGetTypeID() )
  1714.                         {
  1715.                             int64_t i_ipod_id;
  1716.                             CFNumberGetValue( (CFNumberRef)value,
  1717.                                               kCFNumberLongLongType,
  1718.                                               &i_ipod_id );
  1719.                             *p_ipod_id = i_ipod_id;
  1720.                             i_ret = 0;
  1721.                         }
  1722.                         CFRelease( value );
  1723.                     }
  1724.                     IOObjectRelease( device );
  1725.                     if( !i_ret ) break;
  1726.                 }
  1727.                 IOObjectRelease( iterator );
  1728.             }
  1729.         }
  1730.         mach_port_deallocate( mach_task_self(), port );
  1731.     }
  1732. #elif HAVE_SYSFS_LIBSYSFS_H
  1733.     struct sysfs_bus *bus = NULL;
  1734.     struct dlist *devlist = NULL;
  1735.     struct dlist *attributes = NULL;
  1736.     struct sysfs_device *curdev = NULL;
  1737.     struct sysfs_attribute *curattr = NULL;
  1738.     bus = sysfs_open_bus( "ieee1394" );
  1739.     if( bus != NULL )
  1740.     {
  1741.         devlist = sysfs_get_bus_devices( bus );
  1742.         if( devlist != NULL )
  1743.         {
  1744.             dlist_for_each_data( devlist, curdev, struct sysfs_device )
  1745.             {
  1746.                 attributes = sysfs_get_device_attributes( curdev );
  1747.                 if( attributes != NULL )
  1748.                 {
  1749.                     dlist_for_each_data( attributes, curattr,
  1750.                                          struct sysfs_attribute )
  1751.                     {
  1752.                         if( ( strcmp( curattr->name, "model_name" ) == 0 ) &&
  1753.                             ( strncmp( curattr->value, PROD_NAME,
  1754.                                        sizeof(PROD_NAME) ) == 0 ) )
  1755.                         {
  1756.                             *p_ipod_id = strtoll( curdev->name, NULL, 16 );
  1757.                             i_ret = 0;
  1758.                             break;
  1759.                         }
  1760.                     }
  1761.                 }
  1762.                 if( !i_ret ) break;
  1763.             }
  1764.         }
  1765.         sysfs_close_bus( bus );
  1766.     }
  1767. #endif
  1768.     return i_ret;
  1769. }
  1770. #else /* !defined( UNDER_CE ) */
  1771. void *drms_alloc( char *psz_homedir ){ return 0; }
  1772. void drms_free( void *a ){}
  1773. void drms_decrypt( void *a, uint32_t *b, uint32_t c  ){}
  1774. int drms_init( void *a, uint32_t b, uint8_t *c, uint32_t d ){ return -1; }
  1775. #endif /* defined( UNDER_CE ) */