]> git.sesse.net Git - vlc/blob - modules/demux/mp4/drms.c
* modules/demux/mp4/drms.c:
[vlc] / modules / demux / mp4 / drms.c
1 /*****************************************************************************
2  * drms.c: DRMS
3  *****************************************************************************
4  * Copyright (C) 2004 VideoLAN
5  * $Id: drms.c,v 1.5 2004/01/16 18:26:57 sam Exp $
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
25 #include <stdlib.h>                                      /* malloc(), free() */
26
27 #ifdef WIN32
28 #   include <io.h>
29 #else
30 #   include <stdio.h>
31 #endif
32
33 #include <vlc/vlc.h>
34
35 #ifdef HAVE_ERRNO_H
36 #   include <errno.h>
37 #endif
38
39 #ifdef WIN32
40 #   include <tchar.h>
41 #   include <shlobj.h>
42 #   include <windows.h>
43 #endif
44
45 #ifdef HAVE_SYS_STAT_H
46    #include <sys/stat.h>
47 #endif
48 #ifdef HAVE_SYS_TYPES_H
49    #include <sys/types.h>
50 #endif
51
52 #include "drms.h"
53 #include "drmstables.h"
54
55 #include "libmp4.h"
56
57 /*****************************************************************************
58  * aes_s: AES keys structure
59  *****************************************************************************
60  * This structure stores a set of keys usable for encryption and decryption
61  * with the AES/Rijndael algorithm.
62  *****************************************************************************/
63 struct aes_s
64 {
65     uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
66     uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
67 };
68
69 /*****************************************************************************
70  * md5_s: MD5 message structure
71  *****************************************************************************
72  * This structure stores the static information needed to compute an MD5
73  * hash. It has an extra data buffer to allow non-aligned writes.
74  *****************************************************************************/
75 struct md5_s
76 {
77     uint64_t i_bits;      /* Total written bits */
78     uint32_t p_digest[4]; /* The MD5 digest */
79     uint32_t p_data[16];  /* Buffer to cache non-aligned writes */
80 };
81
82 /*****************************************************************************
83  * shuffle_s: shuffle structure
84  *****************************************************************************
85  * This structure stores the static information needed to shuffle data using
86  * a custom algorithm.
87  *****************************************************************************/
88 struct shuffle_s
89 {
90     uint32_t p_commands[ 20 ];
91     uint32_t p_bordel[ 16 ];
92 };
93
94 /*****************************************************************************
95  * drms_s: DRMS structure
96  *****************************************************************************
97  * This structure stores the static information needed to decrypt DRMS data.
98  *****************************************************************************/
99 struct drms_s
100 {
101     uint32_t i_user;
102     uint32_t i_key;
103     uint8_t *p_iviv;
104     uint8_t *p_name;
105     uint32_t i_name_len;
106
107     uint32_t p_key[ 4 ];
108     struct aes_s aes;
109
110     char    *psz_homedir;
111 };
112
113 /*****************************************************************************
114  * Local prototypes
115  *****************************************************************************/
116 static void InitAES       ( struct aes_s *, uint32_t * );
117 static void DecryptAES    ( struct aes_s *, uint32_t *, const uint32_t * );
118
119 static void InitMD5       ( struct md5_s * );
120 static void AddMD5        ( struct md5_s *, const uint8_t *, uint32_t );
121 static void AddNativeMD5  ( struct md5_s *, uint32_t *, uint32_t );
122 static void EndMD5        ( struct md5_s * );
123 static void Digest        ( struct md5_s *, const uint32_t * );
124
125 static void InitShuffle   ( struct shuffle_s *, uint32_t * );
126 static void DoShuffle     ( struct shuffle_s *, uint8_t *, uint32_t );
127 static void Bordelize     ( uint32_t *, uint32_t );
128
129 static int GetSystemKey   ( uint32_t * );
130 static int WriteUserKey   ( void *, uint32_t * );
131 static int ReadUserKey    ( void *, uint32_t * );
132 static int GetUserKey     ( void *, uint32_t * );
133
134 static int GetSCIData     ( uint32_t **, uint32_t * );
135 static int HashSystemInfo ( struct md5_s * );
136
137 /*****************************************************************************
138  * BlockXOR: XOR two 128 bit blocks
139  *****************************************************************************/
140 static inline void BlockXOR( uint32_t *p_dest, uint32_t *p_s1, uint32_t *p_s2 )
141 {
142     uint32_t i;
143
144     for( i = 0; i < 4; i++ )
145     {
146         p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
147     }
148 }
149
150 /*****************************************************************************
151  * drms_alloc: allocate a DRMS structure
152  *****************************************************************************/
153 void *drms_alloc( char *psz_homedir )
154 {
155     struct drms_s *p_drms;
156
157     p_drms = malloc( sizeof(struct drms_s) );
158
159     if( p_drms == NULL )
160     {
161         return NULL;
162     }
163
164     memset( p_drms, 0, sizeof(struct drms_s) );
165
166     p_drms->psz_homedir = malloc( PATH_MAX );
167     if( p_drms->psz_homedir != NULL )
168     {
169         strncpy( p_drms->psz_homedir, psz_homedir, PATH_MAX );
170         p_drms->psz_homedir[ PATH_MAX - 1 ] = '\0';
171     }
172     else
173     {
174         free( (void *)p_drms );
175         p_drms = NULL;
176     }
177
178     return (void *)p_drms;
179 }
180
181 /*****************************************************************************
182  * drms_free: free a previously allocated DRMS structure
183  *****************************************************************************/
184 void drms_free( void *_p_drms )
185 {
186     struct drms_s *p_drms = (struct drms_s *)_p_drms;
187
188     if( p_drms->p_name != NULL )
189     {
190         free( (void *)p_drms->p_name );
191     }
192
193     if( p_drms->p_iviv != NULL )
194     {
195         free( (void *)p_drms->p_iviv );
196     }
197
198     if( p_drms->psz_homedir != NULL )
199     {
200         free( (void *)p_drms->psz_homedir );
201     }
202
203     free( p_drms );
204 }
205
206 /*****************************************************************************
207  * drms_decrypt: unscramble a chunk of data
208  *****************************************************************************/
209 void drms_decrypt( void *_p_drms, uint32_t *p_buffer, uint32_t i_bytes )
210 {
211     struct drms_s *p_drms = (struct drms_s *)_p_drms;
212     uint32_t p_key[ 4 ];
213     uint32_t i_blocks, i;
214
215     /* AES is a block cypher, round down the byte count */
216     i_blocks = i_bytes / 16;
217     i_bytes = i_blocks * 16;
218
219     /* Initialise the key */
220     memcpy( p_key, p_drms->p_key, 4 * sizeof(uint32_t) );
221
222     /* Unscramble */
223     for( i = i_blocks; i--; )
224     {
225         uint32_t  p_tmp[ 4 ];
226
227         DecryptAES( &p_drms->aes, p_tmp, p_buffer );
228         BlockXOR( p_tmp, p_key, p_tmp );
229
230         /* Use the previous scrambled data as the key for next block */
231         memcpy( p_key, p_buffer, 4 * sizeof(uint32_t) );
232
233         /* Copy unscrambled data back to the buffer */
234         memcpy( p_buffer, p_tmp, 4 * sizeof(uint32_t) );
235
236         p_buffer += 4;
237     }
238 }
239
240 /*****************************************************************************
241  * drms_init: initialise a DRMS structure
242  *****************************************************************************/
243 int drms_init( void *_p_drms, uint32_t i_type,
244                uint8_t *p_info, uint32_t i_len )
245 {
246     struct drms_s *p_drms = (struct drms_s *)_p_drms;
247     int i_ret = 0;
248
249     switch( i_type )
250     {
251         case FOURCC_user:
252         {
253             if( i_len < sizeof(p_drms->i_user) )
254             {
255                 i_ret = -1;
256                 break;
257             }
258
259             p_drms->i_user = U32_AT( p_info );
260         }
261         break;
262
263         case FOURCC_key:
264         {
265             if( i_len < sizeof(p_drms->i_key) )
266             {
267                 i_ret = -1;
268                 break;
269             }
270
271             p_drms->i_key = U32_AT( p_info );
272         }
273         break;
274
275         case FOURCC_iviv:
276         {
277             if( i_len < sizeof(p_drms->p_key) )
278             {
279                 i_ret = -1;
280                 break;
281             }
282
283             p_drms->p_iviv = malloc( sizeof(p_drms->p_key) );
284             if( p_drms->p_iviv == NULL )
285             {
286                 i_ret = -1;
287                 break;
288             }
289
290             memcpy( p_drms->p_iviv, p_info, sizeof(p_drms->p_key) );
291         }
292         break;
293
294         case FOURCC_name:
295         {
296             p_drms->i_name_len = strlen( p_info );
297
298             p_drms->p_name = malloc( p_drms->i_name_len );
299             if( p_drms->p_name == NULL )
300             {
301                 i_ret = -1;
302                 break;
303             }
304
305             memcpy( p_drms->p_name, p_info, p_drms->i_name_len );
306         }
307         break;
308
309         case FOURCC_priv:
310         {
311             uint32_t p_priv[ 64 ];
312             struct md5_s md5;
313
314             if( i_len < 64 )
315             {
316                 i_ret = -1;
317                 break;
318             }
319
320             InitMD5( &md5 );
321             AddMD5( &md5, p_drms->p_name, p_drms->i_name_len );
322             AddMD5( &md5, p_drms->p_iviv, sizeof(p_drms->p_key) );
323             EndMD5( &md5 );
324
325             if( GetUserKey( p_drms, p_drms->p_key ) )
326             {
327                 i_ret = -1;
328                 break;
329             }
330
331             InitAES( &p_drms->aes, p_drms->p_key );
332
333             memcpy( p_priv, p_info, 64 );
334             memcpy( p_drms->p_key, md5.p_digest, sizeof(p_drms->p_key) );
335             drms_decrypt( p_drms, p_priv, sizeof(p_priv) );
336
337             InitAES( &p_drms->aes, p_priv + 6 );
338             memcpy( p_drms->p_key, p_priv + 12, sizeof(p_drms->p_key) );
339
340             free( (void *)p_drms->psz_homedir );
341             p_drms->psz_homedir = NULL;
342             free( (void *)p_drms->p_name );
343             p_drms->p_name = NULL;
344             free( (void *)p_drms->p_iviv );
345             p_drms->p_iviv = NULL;
346         }
347         break;
348     }
349
350     return i_ret;
351 }
352
353 /* The following functions are local */
354
355 /*****************************************************************************
356  * InitAES: initialise AES/Rijndael encryption/decryption tables
357  *****************************************************************************
358  * The Advanced Encryption Standard (AES) is described in RFC 3268
359  *****************************************************************************/
360 static void InitAES( struct aes_s *p_aes, uint32_t *p_key )
361 {
362     uint32_t i, t, i_key, i_tmp;
363
364     memset( p_aes->pp_enc_keys[1], 0, 4 * sizeof(uint32_t) );
365     memcpy( p_aes->pp_enc_keys[0], p_key, 4 * sizeof(uint32_t) );
366
367     /* Generate the key tables */
368     i_tmp = p_aes->pp_enc_keys[ 0 ][ 3 ];
369
370     for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
371     {
372         uint32_t j;
373
374         i_tmp = AES_ROR( i_tmp, 8 );
375
376         j = p_aes_table[ i_key ];
377
378         j ^= p_aes_encrypt[ (i_tmp >> 24) & 0xFF ]
379               ^ AES_ROR( p_aes_encrypt[ (i_tmp >> 16) & 0xFF ], 8 )
380               ^ AES_ROR( p_aes_encrypt[ (i_tmp >> 8) & 0xFF ], 16 )
381               ^ AES_ROR( p_aes_encrypt[ i_tmp & 0xFF ], 24 );
382
383         j ^= p_aes->pp_enc_keys[ i_key ][ 0 ];
384         p_aes->pp_enc_keys[ i_key + 1 ][ 0 ] = j;
385         j ^= p_aes->pp_enc_keys[ i_key ][ 1 ];
386         p_aes->pp_enc_keys[ i_key + 1 ][ 1 ] = j;
387         j ^= p_aes->pp_enc_keys[ i_key ][ 2 ];
388         p_aes->pp_enc_keys[ i_key + 1 ][ 2 ] = j;
389         j ^= p_aes->pp_enc_keys[ i_key ][ 3 ];
390         p_aes->pp_enc_keys[ i_key + 1 ][ 3 ] = j;
391
392         i_tmp = j;
393     }
394
395     memcpy( p_aes->pp_dec_keys[ 0 ],
396             p_aes->pp_enc_keys[ 0 ], 4 * sizeof(uint32_t) );
397
398     for( i = 1; i < AES_KEY_COUNT; i++ )
399     {
400         for( t = 0; t < 4; t++ )
401         {
402             uint32_t j, k, l, m, n;
403
404             j = p_aes->pp_enc_keys[ i ][ t ];
405
406             k = (((j >> 7) & 0x01010101) * 27) ^ ((j & 0xFF7F7F7F) << 1);
407             l = (((k >> 7) & 0x01010101) * 27) ^ ((k & 0xFF7F7F7F) << 1);
408             m = (((l >> 7) & 0x01010101) * 27) ^ ((l & 0xFF7F7F7F) << 1);
409
410             j ^= m;
411
412             n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
413
414             p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
415         }
416     }
417 }
418
419 /*****************************************************************************
420  * DecryptAES: decrypt an AES/Rijndael 128 bit block
421  *****************************************************************************/
422 static void DecryptAES( struct aes_s *p_aes,
423                         uint32_t *p_dest, const uint32_t *p_src )
424 {
425     uint32_t p_wtxt[ 4 ]; /* Working cyphertext */
426     uint32_t p_tmp[ 4 ];
427     uint32_t round, t;
428
429     for( t = 0; t < 4; t++ )
430     {
431         /* FIXME: are there any endianness issues here? */
432         p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
433     }
434
435     /* Rounds 0 - 8 */
436     for( round = 0; round < (AES_KEY_COUNT - 1); round++ )
437     {
438         for( t = 0; t < 4; t++ )
439         {
440             p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
441         }
442
443         for( t = 0; t < 4; t++ )
444         {
445             p_wtxt[ t ] = p_tmp[ t ]
446                     ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - round ][ t ];
447         }
448     }
449
450     /* Final round (9) */
451     for( t = 0; t < 4; t++ )
452     {
453         p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
454         p_dest[ t ] ^= p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - round ][ t ];
455     }
456 }
457
458 /*****************************************************************************
459  * InitMD5: initialise an MD5 message
460  *****************************************************************************
461  * The MD5 message-digest algorithm is described in RFC 1321
462  *****************************************************************************/
463 static void InitMD5( struct md5_s *p_md5 )
464 {
465     p_md5->p_digest[ 0 ] = 0x67452301;
466     p_md5->p_digest[ 1 ] = 0xEFCDAB89;
467     p_md5->p_digest[ 2 ] = 0x98BADCFE;
468     p_md5->p_digest[ 3 ] = 0x10325476;
469
470     memset( p_md5->p_data, 0, 16 * sizeof(uint32_t) );
471     p_md5->i_bits = 0;
472 }
473
474 /*****************************************************************************
475  * AddMD5: add i_len bytes to an MD5 message
476  *****************************************************************************/
477 static void AddMD5( struct md5_s *p_md5, const uint8_t *p_src, uint32_t i_len )
478 {
479     uint32_t i_current; /* Current bytes in the spare buffer */
480     uint32_t i_offset = 0;
481
482     i_current = (p_md5->i_bits / 8) & 63;
483
484     p_md5->i_bits += 8 * i_len;
485
486     /* If we can complete our spare buffer to 64 bytes, do it and add the
487      * resulting buffer to the MD5 message */
488     if( i_len >= (64 - i_current) )
489     {
490         memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src,
491                 (64 - i_current) );
492         Digest( p_md5, p_md5->p_data );
493
494         i_offset += (64 - i_current);
495         i_len -= (64 - i_current);
496         i_current = 0;
497     }
498
499     /* Add as many entire 64 bytes blocks as we can to the MD5 message */
500     while( i_len >= 64 )
501     {
502         uint32_t p_tmp[ 16 ];
503         memcpy( p_tmp, p_src + i_offset, 16 * sizeof(uint32_t) );
504         Digest( p_md5, p_tmp );
505         i_offset += 64;
506         i_len -= 64;
507     }
508
509     /* Copy our remaining data to the message's spare buffer */
510     memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src + i_offset, i_len );
511 }
512
513 /*****************************************************************************
514  * AddNativeMD5: add i_len big-endian uin32_t to an MD5 message
515  *****************************************************************************
516  * FIXME: I don't really understand what this is supposed to do, especially
517  * with big values of i_len ...
518  *****************************************************************************/
519 static void AddNativeMD5( struct md5_s *p_md5, uint32_t *p_src, uint32_t i_len )
520 {
521     uint32_t i, x, y;
522     /* XXX: it's 32, not 16! */
523     uint32_t p_tmp[ 32 ];
524
525     /* Convert big endian p_src to native-endian p_tmp */
526     for( x = i_len; x; x -= y )
527     {
528         /* XXX: this looks weird! */
529         y = x > 32 ? 32 : x;
530
531         for( i = 0; i < y; i++ )
532         {
533             p_tmp[ i ] = U32_AT(p_src + i);
534         }
535     }
536
537     AddMD5( p_md5, (uint8_t *)p_tmp, i_len * sizeof(uint32_t) );
538 }
539
540 /*****************************************************************************
541  * EndMD5: finish an MD5 message
542  *****************************************************************************
543  * This function adds adequate padding to the end of the message, and appends
544  * the bit count so that we end at a block boundary.
545  *****************************************************************************/
546 static void EndMD5( struct md5_s *p_md5 )
547 {
548     uint32_t i_current;
549
550     i_current = (p_md5->i_bits / 8) & 63;
551
552     /* Append 0x80 to our buffer. No boundary check because the temporary
553      * buffer cannot be full, otherwise AddMD5 would have emptied it. */
554     ((uint8_t *)p_md5->p_data)[ i_current++ ] = 0x80;
555
556     /* If less than 8 bytes are available at the end of the block, complete
557      * this 64 bytes block with zeros and add it to the message. We'll add
558      * our length at the end of the next block. */
559     if( i_current > 56 )
560     {
561         memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (64 - i_current) );
562         Digest( p_md5, p_md5->p_data );
563         i_current = 0;
564     }
565
566     /* Fill the unused space in our last block with zeroes and put the
567      * message length at the end. */
568     memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (56 - i_current) );
569     p_md5->p_data[ 14 ] = p_md5->i_bits & 0xffffffff;
570     p_md5->p_data[ 15 ] = (p_md5->i_bits >> 32);
571
572     Digest( p_md5, p_md5->p_data );
573 }
574
575 #define F1( x, y, z ) ((z) ^ ((x) & ((y) ^ (z))))
576 #define F2( x, y, z ) F1((z), (x), (y))
577 #define F3( x, y, z ) ((x) ^ (y) ^ (z))
578 #define F4( x, y, z ) ((y) ^ ((x) | ~(z)))
579
580 #define MD5_DO( f, w, x, y, z, data, s ) \
581     ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
582
583 /*****************************************************************************
584  * Digest: update the MD5 digest with 64 bytes of data
585  *****************************************************************************/
586 static void Digest( struct md5_s *p_md5, const uint32_t *p_input )
587 {
588     uint32_t a, b, c, d;
589
590     a = p_md5->p_digest[ 0 ];
591     b = p_md5->p_digest[ 1 ];
592     c = p_md5->p_digest[ 2 ];
593     d = p_md5->p_digest[ 3 ];
594
595     MD5_DO( F1, a, b, c, d, p_input[  0 ] + 0xd76aa478,  7 );
596     MD5_DO( F1, d, a, b, c, p_input[  1 ] + 0xe8c7b756, 12 );
597     MD5_DO( F1, c, d, a, b, p_input[  2 ] + 0x242070db, 17 );
598     MD5_DO( F1, b, c, d, a, p_input[  3 ] + 0xc1bdceee, 22 );
599     MD5_DO( F1, a, b, c, d, p_input[  4 ] + 0xf57c0faf,  7 );
600     MD5_DO( F1, d, a, b, c, p_input[  5 ] + 0x4787c62a, 12 );
601     MD5_DO( F1, c, d, a, b, p_input[  6 ] + 0xa8304613, 17 );
602     MD5_DO( F1, b, c, d, a, p_input[  7 ] + 0xfd469501, 22 );
603     MD5_DO( F1, a, b, c, d, p_input[  8 ] + 0x698098d8,  7 );
604     MD5_DO( F1, d, a, b, c, p_input[  9 ] + 0x8b44f7af, 12 );
605     MD5_DO( F1, c, d, a, b, p_input[ 10 ] + 0xffff5bb1, 17 );
606     MD5_DO( F1, b, c, d, a, p_input[ 11 ] + 0x895cd7be, 22 );
607     MD5_DO( F1, a, b, c, d, p_input[ 12 ] + 0x6b901122,  7 );
608     MD5_DO( F1, d, a, b, c, p_input[ 13 ] + 0xfd987193, 12 );
609     MD5_DO( F1, c, d, a, b, p_input[ 14 ] + 0xa679438e, 17 );
610     MD5_DO( F1, b, c, d, a, p_input[ 15 ] + 0x49b40821, 22 );
611
612     MD5_DO( F2, a, b, c, d, p_input[  1 ] + 0xf61e2562,  5 );
613     MD5_DO( F2, d, a, b, c, p_input[  6 ] + 0xc040b340,  9 );
614     MD5_DO( F2, c, d, a, b, p_input[ 11 ] + 0x265e5a51, 14 );
615     MD5_DO( F2, b, c, d, a, p_input[  0 ] + 0xe9b6c7aa, 20 );
616     MD5_DO( F2, a, b, c, d, p_input[  5 ] + 0xd62f105d,  5 );
617     MD5_DO( F2, d, a, b, c, p_input[ 10 ] + 0x02441453,  9 );
618     MD5_DO( F2, c, d, a, b, p_input[ 15 ] + 0xd8a1e681, 14 );
619     MD5_DO( F2, b, c, d, a, p_input[  4 ] + 0xe7d3fbc8, 20 );
620     MD5_DO( F2, a, b, c, d, p_input[  9 ] + 0x21e1cde6,  5 );
621     MD5_DO( F2, d, a, b, c, p_input[ 14 ] + 0xc33707d6,  9 );
622     MD5_DO( F2, c, d, a, b, p_input[  3 ] + 0xf4d50d87, 14 );
623     MD5_DO( F2, b, c, d, a, p_input[  8 ] + 0x455a14ed, 20 );
624     MD5_DO( F2, a, b, c, d, p_input[ 13 ] + 0xa9e3e905,  5 );
625     MD5_DO( F2, d, a, b, c, p_input[  2 ] + 0xfcefa3f8,  9 );
626     MD5_DO( F2, c, d, a, b, p_input[  7 ] + 0x676f02d9, 14 );
627     MD5_DO( F2, b, c, d, a, p_input[ 12 ] + 0x8d2a4c8a, 20 );
628
629     MD5_DO( F3, a, b, c, d, p_input[  5 ] + 0xfffa3942,  4 );
630     MD5_DO( F3, d, a, b, c, p_input[  8 ] + 0x8771f681, 11 );
631     MD5_DO( F3, c, d, a, b, p_input[ 11 ] + 0x6d9d6122, 16 );
632     MD5_DO( F3, b, c, d, a, p_input[ 14 ] + 0xfde5380c, 23 );
633     MD5_DO( F3, a, b, c, d, p_input[  1 ] + 0xa4beea44,  4 );
634     MD5_DO( F3, d, a, b, c, p_input[  4 ] + 0x4bdecfa9, 11 );
635     MD5_DO( F3, c, d, a, b, p_input[  7 ] + 0xf6bb4b60, 16 );
636     MD5_DO( F3, b, c, d, a, p_input[ 10 ] + 0xbebfbc70, 23 );
637     MD5_DO( F3, a, b, c, d, p_input[ 13 ] + 0x289b7ec6,  4 );
638     MD5_DO( F3, d, a, b, c, p_input[  0 ] + 0xeaa127fa, 11 );
639     MD5_DO( F3, c, d, a, b, p_input[  3 ] + 0xd4ef3085, 16 );
640     MD5_DO( F3, b, c, d, a, p_input[  6 ] + 0x04881d05, 23 );
641     MD5_DO( F3, a, b, c, d, p_input[  9 ] + 0xd9d4d039,  4 );
642     MD5_DO( F3, d, a, b, c, p_input[ 12 ] + 0xe6db99e5, 11 );
643     MD5_DO( F3, c, d, a, b, p_input[ 15 ] + 0x1fa27cf8, 16 );
644     MD5_DO( F3, b, c, d, a, p_input[  2 ] + 0xc4ac5665, 23 );
645
646     MD5_DO( F4, a, b, c, d, p_input[  0 ] + 0xf4292244,  6 );
647     MD5_DO( F4, d, a, b, c, p_input[  7 ] + 0x432aff97, 10 );
648     MD5_DO( F4, c, d, a, b, p_input[ 14 ] + 0xab9423a7, 15 );
649     MD5_DO( F4, b, c, d, a, p_input[  5 ] + 0xfc93a039, 21 );
650     MD5_DO( F4, a, b, c, d, p_input[ 12 ] + 0x655b59c3,  6 );
651     MD5_DO( F4, d, a, b, c, p_input[  3 ] + 0x8f0ccc92, 10 );
652     MD5_DO( F4, c, d, a, b, p_input[ 10 ] + 0xffeff47d, 15 );
653     MD5_DO( F4, b, c, d, a, p_input[  1 ] + 0x85845dd1, 21 );
654     MD5_DO( F4, a, b, c, d, p_input[  8 ] + 0x6fa87e4f,  6 );
655     MD5_DO( F4, d, a, b, c, p_input[ 15 ] + 0xfe2ce6e0, 10 );
656     MD5_DO( F4, c, d, a, b, p_input[  6 ] + 0xa3014314, 15 );
657     MD5_DO( F4, b, c, d, a, p_input[ 13 ] + 0x4e0811a1, 21 );
658     MD5_DO( F4, a, b, c, d, p_input[  4 ] + 0xf7537e82,  6 );
659     MD5_DO( F4, d, a, b, c, p_input[ 11 ] + 0xbd3af235, 10 );
660     MD5_DO( F4, c, d, a, b, p_input[  2 ] + 0x2ad7d2bb, 15 );
661     MD5_DO( F4, b, c, d, a, p_input[  9 ] + 0xeb86d391, 21 );
662
663     p_md5->p_digest[ 0 ] += a;
664     p_md5->p_digest[ 1 ] += b;
665     p_md5->p_digest[ 2 ] += c;
666     p_md5->p_digest[ 3 ] += d;
667 }
668
669 /*****************************************************************************
670  * InitShuffle: initialise a shuffle structure
671  *****************************************************************************
672  * This function initialises tables in the p_shuffle structure that will be
673  * used later by DoShuffle. The only external parameter is p_sys_key.
674  *****************************************************************************/
675 static void InitShuffle( struct shuffle_s *p_shuffle, uint32_t *p_sys_key )
676 {
677     uint32_t p_native_key[ 4 ];
678     uint32_t i, i_seed = 0x5476212A; /* *!vT */
679
680     /* Store the system key in native endianness */
681     for( i = 0; i < 4; i++ )
682     {
683         p_native_key[ i ] = U32_AT(p_sys_key + i);
684     }
685
686     /* Fill p_commands using the native key and our seed */
687     for( i = 0; i < 20; i++ )
688     {
689         struct md5_s md5;
690         int32_t i_hash;
691
692         InitMD5( &md5 );
693         AddNativeMD5( &md5, p_native_key, 4 );
694         AddNativeMD5( &md5, &i_seed, 1 );
695         EndMD5( &md5 );
696
697         i_seed++;
698
699         i_hash = ((int32_t)U32_AT(md5.p_digest)) % 1024;
700
701         p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
702     }
703
704     /* Fill p_bordel with completely meaningless initial values.
705      * FIXME: check endianness issues. */
706     p_shuffle->p_bordel[  0 ] = p_native_key[ 0 ];
707     p_shuffle->p_bordel[  1 ] = 0x68723876; /* v8rh */
708     p_shuffle->p_bordel[  2 ] = 0x41617376; /* vsaA */
709     p_shuffle->p_bordel[  3 ] = 0x4D4B4F76; /* voKM */
710
711     p_shuffle->p_bordel[  4 ] = p_native_key[ 1 ];
712     p_shuffle->p_bordel[  5 ] = 0x48556646; /* FfUH */
713     p_shuffle->p_bordel[  6 ] = 0x38393725; /* %798 */
714     p_shuffle->p_bordel[  7 ] = 0x2E3B5B3D; /* =[;. */
715
716     p_shuffle->p_bordel[  8 ] = p_native_key[ 2 ];
717     p_shuffle->p_bordel[  9 ] = 0x37363866; /* f867 */
718     p_shuffle->p_bordel[ 10 ] = 0x30383637; /* 7680 */
719     p_shuffle->p_bordel[ 11 ] = 0x34333661; /* a634 */
720
721     p_shuffle->p_bordel[ 12 ] = p_native_key[ 3 ];
722     p_shuffle->p_bordel[ 13 ] = 0x37386162; /* ba87 */
723     p_shuffle->p_bordel[ 14 ] = 0x494F6E66; /* fnOI */
724     p_shuffle->p_bordel[ 15 ] = 0x2A282966; /* f)(* */
725 }
726
727 /*****************************************************************************
728  * DoShuffle: shuffle i_len bytes of a buffer
729  *****************************************************************************
730  * This is so ugly and uses so many MD5 checksums that it is most certainly
731  * one-way, though why it needs to be so complicated is beyond me.
732  *****************************************************************************/
733 static void DoShuffle( struct shuffle_s *p_shuffle,
734                        uint8_t *p_buffer, uint32_t i_len )
735 {
736     struct md5_s md5;
737     uint32_t i;
738
739     /* Randomize p_bordel and compute its MD5 checksum */
740     for( i = 0; i < 20; i++ )
741     {
742         if( p_shuffle->p_commands[ i ] )
743         {
744             Bordelize( p_shuffle->p_bordel, p_shuffle->p_commands[ i ] );
745         }
746     }
747
748     InitMD5( &md5 );
749     AddNativeMD5( &md5, p_shuffle->p_bordel, 16 );
750     EndMD5( &md5 );
751
752     /* There are only 16 bytes in an MD5 hash */
753     if( i_len > 16 )
754     {
755         i_len = 16;
756     }
757
758     /* XOR our buffer with the computed checksum */
759     for( i = 0; i < i_len; i++ )
760     {
761         p_buffer[ i ] ^= ((uint8_t *)&md5.p_digest)[ i ];
762     }
763 }
764
765 /*****************************************************************************
766  * Bordelize: helper for DoShuffle
767  *****************************************************************************
768  * Using the MD5 hash of a string is probably not one-way enough. This
769  * function randomises p_bordel depending on the value of i_command to make
770  * things even more messy in p_bordel.
771  *****************************************************************************/
772 static void Bordelize( uint32_t *p_bordel, uint32_t i_command )
773 {
774     uint32_t i, x;
775
776     i = (i_command / 16) & 15;
777     x = (~(i_command & 15)) & 15;
778
779     if( (i_command & 768) == 768 )
780     {
781         x = (~i) & 15;
782         i = i_command & 15;
783
784         p_bordel[ i ] = p_bordel[ ((16 - x) & 15) ] + p_bordel[ (15 - x) ];
785     }
786     else if( (i_command & 512) == 512 )
787     {
788         p_bordel[ i ] ^= p_shuffle_xor[ 15 - i ][ x ];
789     }
790     else if( (i_command & 256) == 256 )
791     {
792         p_bordel[ i ] -= p_shuffle_sub[ 15 - i ][ x ];
793     }
794     else
795     {
796         p_bordel[ i ] += p_shuffle_add[ 15 - i ][ x ];
797     }
798 }
799
800 /*****************************************************************************
801  * GetSystemKey: get the system key
802  *****************************************************************************
803  * Compute the system key from various system information, see HashSystemInfo.
804  *****************************************************************************/
805 static int GetSystemKey( uint32_t *p_sys_key )
806 {
807     struct md5_s md5;
808     uint32_t p_tmp_key[ 4 ];
809
810     InitMD5( &md5 );
811     if( HashSystemInfo( &md5 ) )
812     {
813         return -1;
814     }
815     EndMD5( &md5 );
816
817     /* Write our digest to p_tmp_key */
818     memcpy( p_tmp_key, md5.p_digest, 4 * sizeof(uint32_t) );
819
820     InitMD5( &md5 );
821     AddMD5( &md5, "YuaFlafu", 8 );
822     AddMD5( &md5, (uint8_t *)p_tmp_key, 6 );
823     AddMD5( &md5, (uint8_t *)p_tmp_key, 6 );
824     AddMD5( &md5, (uint8_t *)p_tmp_key, 6 );
825     AddMD5( &md5, "zPif98ga", 8 );
826     EndMD5( &md5 );
827
828     memcpy( p_sys_key, md5.p_digest, 4 * sizeof(uint32_t) );
829
830     return 0;
831 }
832
833 #ifdef WIN32
834 #   define DRMS_DIRNAME "drms"
835 #else
836 #   define DRMS_DIRNAME ".drms"
837 #endif
838
839 /*****************************************************************************
840  * WriteUserKey: write the user key to hard disk
841  *****************************************************************************
842  * Write the user key to the hard disk so that it can be reused later or used
843  * on operating systems other than Win32.
844  *****************************************************************************/
845 static int WriteUserKey( void *_p_drms, uint32_t *p_user_key )
846 {
847     struct drms_s *p_drms = (struct drms_s *)_p_drms;
848     FILE *file;
849     int i_ret = -1;
850     char psz_path[ PATH_MAX ];
851
852     snprintf( psz_path, PATH_MAX - 1,
853               "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
854
855 #if defined( HAVE_ERRNO_H )
856 #   if defined( WIN32 )
857     if( !mkdir( psz_path ) || errno == EEXIST )
858 #   else
859     if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
860 #   endif
861 #else
862     if( !mkdir( psz_path ) )
863 #endif
864     {
865         snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d",
866                   p_drms->psz_homedir, p_drms->i_user, p_drms->i_key );
867
868         file = fopen( psz_path, "w" );
869         if( file != NULL )
870         {
871             i_ret = fwrite( p_user_key, sizeof(uint32_t),
872                             4, file ) == 4 ? 0 : -1;
873             fclose( file );
874         }
875     }
876
877     return i_ret;
878 }
879
880 /*****************************************************************************
881  * ReadUserKey: read the user key from hard disk
882  *****************************************************************************
883  * Retrieve the user key from the hard disk if available.
884  *****************************************************************************/
885 static int ReadUserKey( void *_p_drms, uint32_t *p_user_key )
886 {
887     struct drms_s *p_drms = (struct drms_s *)_p_drms;
888     FILE *file;
889     int i_ret = -1;
890     char psz_path[ PATH_MAX ];
891
892     snprintf( psz_path, PATH_MAX - 1,
893               "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir,
894               p_drms->i_user, p_drms->i_key );
895
896     file = fopen( psz_path, "r" );
897     if( file != NULL )
898     {
899         i_ret = fread( p_user_key, sizeof(uint32_t),
900                        4, file ) == 4 ? 0 : -1;
901         fclose( file );
902     }
903
904     return i_ret;
905 }
906
907 /*****************************************************************************
908  * GetUserKey: get the user key
909  *****************************************************************************
910  * Retrieve the user key from the hard disk if available, otherwise generate
911  * it from the system key. If the key could be successfully generated, write
912  * it to the hard disk for future use.
913  *****************************************************************************/
914 static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
915 {
916     struct drms_s *p_drms = (struct drms_s *)_p_drms;
917     struct aes_s aes;
918     struct shuffle_s shuffle;
919     uint32_t i, y;
920     uint32_t *p_tmp;
921     uint32_t *p_cur_key;
922     uint32_t p_sys_key[ 4 ];
923     uint32_t i_sci_size;
924     uint32_t *pp_sci[ 2 ];
925     int i_ret = -1;
926
927     uint32_t p_sci_key[ 4 ] =
928     {
929         0x6e66556d, /* nfUm */
930         0x6e676f70, /* ngop */
931         0x67666461, /* gfda */
932         0x33373866  /* 378f */
933     };
934
935     if( !ReadUserKey( p_drms, p_user_key ) )
936     {
937         return 0;
938     }
939
940     if( GetSystemKey( p_sys_key ) )
941     {
942         return -1;
943     }
944
945     if( GetSCIData( pp_sci + 0, &i_sci_size ) )
946     {
947         return -1;
948     }
949
950     p_tmp = pp_sci[ 0 ];
951     pp_sci[ 1 ] = (uint32_t *)(((uint8_t *)pp_sci[ 0 ]) + i_sci_size);
952     i_sci_size -= sizeof(*pp_sci[ 0 ]);
953
954     InitAES( &aes, p_sys_key );
955
956     for( i = 0, p_cur_key = p_sci_key;
957          i < i_sci_size / sizeof(p_drms->p_key); i++ )
958     {
959         y = i * sizeof(*pp_sci[ 0 ]);
960
961         DecryptAES( &aes, pp_sci[ 1 ] + y + 1, pp_sci[ 0 ] + y + 1 );
962         BlockXOR( pp_sci[ 1 ] + y + 1, p_cur_key, pp_sci[ 1 ] + y + 1 );
963
964         p_cur_key = pp_sci[ 0 ] + y + 1;
965     }
966
967     /* Shuffle pp_sci[ 1 ] using a custom routine */
968     InitShuffle( &shuffle, p_sys_key );
969
970     for( i = 0; i < i_sci_size / sizeof(p_drms->p_key); i++ )
971     {
972         y = i * sizeof(*pp_sci[ 1 ]);
973
974         DoShuffle( &shuffle, (uint8_t *)(pp_sci[ 1 ] + y + 1),
975                    sizeof(p_drms->p_key) );
976     }
977
978     y = 0;
979     i = U32_AT( &pp_sci[ 1 ][ 5 ] );
980     i_sci_size -= 21 * sizeof(*pp_sci[ 1 ]);
981     pp_sci[ 1 ] += 22;
982     pp_sci[ 0 ] = NULL;
983
984     while( i_sci_size > 0 && i > 0 )
985     {
986         if( pp_sci[ 0 ] == NULL )
987         {
988             i_sci_size -= 18 * sizeof(*pp_sci[ 1 ]);
989             if( i_sci_size <= 0 )
990             {
991                 break;
992             }
993
994             pp_sci[ 0 ] = pp_sci[ 1 ];
995             y = U32_AT( &pp_sci[ 1 ][ 17 ] );
996             pp_sci[ 1 ] += 18;
997         }
998
999         if( !y )
1000         {
1001             i--;
1002             pp_sci[ 0 ] = NULL;
1003             continue;
1004         }
1005
1006         if( U32_AT( &pp_sci[ 0 ][ 0 ] ) == p_drms->i_user &&
1007             ( i_sci_size >=
1008               (sizeof(p_drms->p_key) + sizeof(pp_sci[ 1 ][ 0 ]) ) ) &&
1009             ( ( U32_AT( &pp_sci[ 1 ][ 0 ] ) == p_drms->i_key ) ||
1010               ( !p_drms->i_key ) || ( pp_sci[ 1 ] == (pp_sci[ 0 ] + 18) ) ) )
1011         {
1012             memcpy( p_user_key, &pp_sci[ 1 ][ 1 ], sizeof(p_drms->p_key) );
1013             WriteUserKey( p_drms, p_user_key );
1014             i_ret = 0;
1015             break;
1016         }
1017
1018         y--;
1019         pp_sci[ 1 ] += 5;
1020         i_sci_size -= 5 * sizeof(*pp_sci[ 1 ]);
1021     }
1022
1023     free( (void *)p_tmp );
1024
1025     return i_ret;
1026 }
1027
1028 /*****************************************************************************
1029  * GetSCIData: get SCI data from "SC Info.sidb"
1030  *****************************************************************************
1031  * Read SCI data from "\Apple Computer\iTunes\SC Info\SC Info.sidb"
1032  *****************************************************************************/
1033 static int GetSCIData( uint32_t **pp_sci, uint32_t *p_sci_size )
1034 {
1035     int i_ret = -1;
1036
1037 #ifdef WIN32
1038     HANDLE i_file;
1039     DWORD i_size, i_read;
1040     TCHAR p_path[ PATH_MAX ];
1041     TCHAR *p_filename = _T("\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb");
1042
1043     typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
1044                                                LPTSTR );
1045
1046     HINSTANCE shfolder_dll = NULL;
1047     SHGETFOLDERPATH dSHGetFolderPath = NULL;
1048
1049     if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
1050     {
1051         dSHGetFolderPath =
1052             (SHGETFOLDERPATH)GetProcAddress( shfolder_dll,
1053 #ifdef _UNICODE
1054                                              _T("SHGetFolderPathW") );
1055 #else
1056                                              _T("SHGetFolderPathA") );
1057 #endif
1058     }
1059
1060     if( dSHGetFolderPath != NULL &&
1061         SUCCEEDED( dSHGetFolderPath( NULL, CSIDL_COMMON_APPDATA,
1062                                      NULL, 0, p_path ) ) )
1063     {
1064         _tcsncat( p_path, p_filename, min( _tcslen( p_filename ),
1065                   (PATH_MAX-1) - _tcslen( p_path ) ) );
1066
1067         i_file = CreateFile( p_path, GENERIC_READ, 0, NULL,
1068                              OPEN_EXISTING, 0, NULL );
1069         if( i_file != INVALID_HANDLE_VALUE )
1070         {
1071             i_size = GetFileSize( i_file, NULL );
1072             if( i_size != INVALID_FILE_SIZE &&
1073                 i_size > (sizeof(*pp_sci[ 0 ]) * 22) )
1074             {
1075                 *pp_sci = malloc( i_size * 2 );
1076                 if( *pp_sci != NULL )
1077                 {
1078                     if( ReadFile( i_file, *pp_sci, i_size, &i_read, NULL ) &&
1079                         i_read == i_size )
1080                     {
1081                         *p_sci_size = i_size;
1082                         i_ret = 0;
1083                     }
1084                     else
1085                     {
1086                         free( (void *)*pp_sci );
1087                         *pp_sci = NULL;
1088                     }
1089                 }
1090             }
1091
1092             CloseHandle( i_file );
1093         }
1094     }
1095
1096     if( shfolder_dll != NULL )
1097     {
1098         FreeLibrary( shfolder_dll );
1099     }
1100 #endif
1101
1102     return i_ret;
1103 }
1104
1105 /*****************************************************************************
1106  * HashSystemInfo: add system information to an MD5 hash
1107  *****************************************************************************
1108  * This function adds the C: hard drive serial number, BIOS version, CPU type
1109  * and Windows version to an MD5 hash.
1110  *****************************************************************************/
1111 static int HashSystemInfo( struct md5_s *p_md5 )
1112 {
1113     int i_ret = 0;
1114
1115 #ifdef WIN32
1116     HKEY i_key;
1117     uint32_t i;
1118     DWORD i_size;
1119     DWORD i_serial;
1120     LPBYTE p_reg_buf;
1121
1122     static LPCTSTR p_reg_keys[ 3 ][ 2 ] =
1123     {
1124         {
1125             _T("HARDWARE\\DESCRIPTION\\System"),
1126             _T("SystemBiosVersion")
1127         },
1128
1129         {
1130             _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
1131             _T("ProcessorNameString")
1132         },
1133
1134         {
1135             _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
1136             _T("ProductId")
1137         }
1138     };
1139
1140     AddMD5( p_md5, "cache-control", 13 );
1141     AddMD5( p_md5, "Ethernet", 8 );
1142
1143     GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
1144                           NULL, NULL, NULL, 0 );
1145     AddMD5( p_md5, (uint8_t *)&i_serial, 4 );
1146
1147     for( i = 0; i < sizeof(p_reg_keys)/sizeof(p_reg_keys[ 0 ]); i++ )
1148     {
1149         if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
1150                           0, KEY_READ, &i_key ) != ERROR_SUCCESS )
1151         {
1152             continue;
1153         }
1154
1155         if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1156                              NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
1157         {
1158             RegCloseKey( i_key );
1159             continue;
1160         }
1161
1162         p_reg_buf = malloc( i_size );
1163
1164         if( p_reg_buf != NULL )
1165         {
1166             if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1167                                  NULL, NULL, p_reg_buf,
1168                                  &i_size ) == ERROR_SUCCESS )
1169             {
1170                 AddMD5( p_md5, (uint8_t *)p_reg_buf, i_size );
1171             }
1172
1173             free( p_reg_buf );
1174         }
1175
1176         RegCloseKey( i_key );
1177     }
1178
1179 #else
1180     i_ret = -1;
1181 #endif
1182
1183     return i_ret;
1184 }
1185