css-auth.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:8k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) 1999
  3.  *  Derek Fawcus <derek@spider.com>
  4.  * Mark Roberts <maroberts@dial.pipex.com>
  5.  * This code may be used under the terms of Version 2 of the GPL,
  6.  * read the file COPYING for details.
  7.  *
  8.  */
  9. #include <stdio.h>
  10. #include "css.h"
  11. #include "css-auth.h"
  12. typedef unsigned long u32;
  13. /*
  14.  * We use two LFSR's (seeded from some of the input data bytes) to
  15.  * generate two streams of pseudo-random bits.  These two bit streams
  16.  * are then combined by simply adding with carry to generate a final
  17.  * sequence of pseudo-random bits which is stored in the buffer that
  18.  * 'output' points to the end of - len is the size of this buffer.
  19.  *
  20.  * The first LFSR is of degree 25,  and has a polynomial of:
  21.  * x^13 + x^5 + x^4 + x^1 + 1
  22.  *
  23.  * The second LSFR is of degree 17,  and has a (primitive) polynomial of:
  24.  * x^15 + x^1 + 1
  25.  *
  26.  * I don't know if these polynomials are primitive modulo 2,  and thus
  27.  * represent maximal-period LFSR's.
  28.  *
  29.  *
  30.  * Note that we take the output of each LFSR from the new shifted in
  31.  * bit,  not the old shifted out bit.  Thus for ease of use the LFSR's
  32.  * are implemented in bit reversed order.
  33.  *
  34.  */
  35. static void generate_bits(byte *output, int len, byte *s)
  36. {
  37. u32 lfsr0, lfsr1;
  38. int val;
  39. byte o_lfsr0, o_lfsr1;
  40. /* In order to ensure that the LFSR works we need to ensure that the
  41.  * initial values are non-zero.  Thus when we initialise them from
  42.  * the seed,  we ensure that a bit is set.
  43.  */
  44. lfsr0 = (s[0] << 17) | (s[1] << 9) | ((s[2] & ~7) << 1) | 8 | (s[2] & 7);
  45. /*
  46.   reverse lfsr0/1 to simplify calculation in loop
  47. */
  48. lfsr0 = (reverse[lfsr0&0xff]<<17) | (reverse[(lfsr0>>8)&0xff] << 9)
  49.   | (reverse[(lfsr0>>16)&0xff]<<1) |(lfsr0>>24);
  50. lfsr1 = (reverse[s[4]] << 9) | 0x100 | ( reverse[ s[3]] );
  51. ++output;
  52. val = 0;
  53. do {
  54. /*
  55. reversed verion of
  56. o_lfsr0 = (lfsr0 >> 17) ^ (lfsr0 >> 14) ^ (lfsr0 >> 13) ^ (lfsr0 >> 5);
  57. lfsr0 = (lfsr0 << 8) ^ o_lfsr0
  58. o_lfsr1 = lfsr1 & 7;
  59. o_lfsr1 = (o_lfsr1 << 5) ^ (o_lfsr1 << 2) ^ (o_lfsr1 >> 1);
  60. o_lfsr1 ^= (lfsr1 >> 9) ^ (lfsr1 >> 12) ^ (lfsr1 >> 15);
  61. lfsr1 = (lfsr1 << 8) ^ o_lfsr1
  62. */
  63. o_lfsr0 = (lfsr0 >> 12) ^ (lfsr0 >> 4) ^  (lfsr0 >> 3) ^ lfsr0;
  64. o_lfsr1 = ((lfsr1 >> 14) & 7) ^ lfsr1;
  65. o_lfsr1 ^= (o_lfsr1 << 3) ^ (o_lfsr1 << 6);
  66. lfsr1 = (lfsr1 >> 8) ^ (o_lfsr1 << 9);
  67. lfsr0 = (lfsr0 >> 8) ^ (o_lfsr0 << 17);
  68. o_lfsr0 = ~o_lfsr0;
  69. o_lfsr1 = ~o_lfsr1;
  70. val += o_lfsr0 + o_lfsr1;
  71. *--output = val & 0xFF;
  72. val >>= 8;
  73. #if (CSSDEBUG & 2)
  74. fprintf(stderr, "lfsr0=%08x lfsr1=%08xn", lfsr0, lfsr1);
  75. #endif
  76. } while (--len > 0);
  77. }
  78. /*-----------------------------------------------------------------------*
  79. If this was C++, these would be inline functions
  80.  *-----------------------------------------------------------------------*/
  81. #define MANGLE1(bs,ip,op) 
  82. in = ip; out = op; bp = bs;                       
  83. for (i = 5, term = 0; --i >= 0; term = in[i]) {   
  84. index = bp[i] ^ in[i];                
  85. index = CSSmangle1[index] ^ cse;              
  86. out[i] = CSSmangle2[index] ^ term;            
  87.         }
  88. #define MANGLE2( bs, ip, op) 
  89. in = ip; out = op; bp = bs;                                
  90. for (i = 5, term = 0; --i >= 0; term = in[i]) {   
  91. index = bp[i] ^ in[i];                
  92. index = CSSmangle1[index] ^ cse;              
  93. index = CSSmangle2[index] ^ term;             
  94.                 out[i] = CSSmangle0[index];                   
  95.         }
  96. /*
  97.  * This encryption engine implements one of 32 variations
  98.  * one the same theme depending upon the choice in the
  99.  * varient parameter (0 - 31).
  100.  *
  101.  * The algorithm itself manipulates a 40 bit input into
  102.  * a 40 bit output.
  103.  * The parameter 'input' is 80 bits.  It consists of
  104.  * the 40 bit input value that is to be encrypted followed
  105.  * by a 40 bit seed value for the pseudo random number
  106.  * generators.
  107.  */
  108. static void engine(int varient, const byte *input, byte *output)
  109. {
  110. byte cse, term, index;
  111. byte temp1[5], temp2[5];
  112. byte bits[30];
  113. const byte *in;
  114. byte *out;
  115.         byte *bp;
  116. int i;
  117. /* Feed the secret into the input values such that
  118.  * we alter the seed to the LFSR's used above,  then
  119.  * generate the bits to play with.
  120.  */
  121. for (i = 5; --i >= 0; )
  122. temp1[i] = input[5 + i] ^ CSSsecret[i];
  123. generate_bits(&bits[29], sizeof bits, &temp1[0]);
  124. #if (CSSDEBUG & 1)
  125. fprintf(stderr, "nBits: ");
  126. print_tab( &bits[0], 30);
  127. #endif
  128. /* This term is used throughout the following to
  129.  * select one of 32 different variations on the
  130.  * algorithm.
  131.  */
  132. cse = CSSvarients[varient];
  133. /* Now the actual blocks doing the encryption.  Each
  134.  * of these works on 40 bits at a time and are quite
  135.  * similar.
  136.  */
  137. MANGLE1( &bits[25], input, &temp1[0]);
  138. out[4] ^= out[0];
  139. #if (CSSDEBUG & 1)
  140. fprintf(stderr"nRound 1: ");
  141. print_tab( &out[0], 5);
  142. #endif
  143. MANGLE1( &bits[20], &temp1[0], &temp2[0]);
  144. out[4] ^= out[0];
  145. #if (CSSDEBUG & 1)
  146. fprintf(stderr, "nRound 2: ");
  147. print_tab( &out[0], 5);
  148. #endif
  149. MANGLE2( &bits[15], temp2, temp1);
  150. out[4] ^= out[0];
  151. #if (CSSDEBUG & 1)
  152. fprintf( stderr, "nRound 3: ");
  153. print_tab( &out[0], 5);
  154. #endif
  155. MANGLE2( &bits[10], temp1, temp2);
  156. out[4] ^= out[0];
  157. #if (CSSDEBUG & 1)
  158. fprintf(stderr, "nRound 4: ");
  159. print_tab( &out[0], 5);
  160. #endif
  161. MANGLE1( &bits[5], temp2, temp1);
  162. out[4] ^= out[0];
  163. #if (CSSDEBUG & 1)
  164. fprintf(stderr, "nRound 5: ");
  165. print_tab( &out[0], 5);
  166. #endif
  167. MANGLE1( &bits[0], temp1, output);
  168. #if (CSSDEBUG & 1)
  169. fprintf(stderr, "nRound 6: ");
  170. print_tab( &out[0], 5);
  171. #endif
  172. }
  173. /*
  174.  * These routines do some reordering of the supplied data before
  175.  * calling engine() to do the main work.
  176.  *
  177.  * The reordering seems similar to that done by the initial stages of
  178.  * the DES algorithm, in that it looks like it's just been done to
  179.  * try and make software decoding slower.  I'm not sure that it
  180.  * actually adds anything to the security.
  181.  *
  182.  * The nature of the shuffling is that the bits of the supplied
  183.  * parameter 'varient' are reorganised (and some inverted),  and
  184.  * the bytes of the parameter 'challenge' are reorganised.
  185.  *
  186.  * The reorganisation in each routine is different,  and the first
  187.  * (CryptKey1) does not bother of play with the 'varient' parameter.
  188.  *
  189.  * Since this code is only run once per disk change,  I've made the
  190.  * code table driven in order to improve readability.
  191.  *
  192.  * Since these routines are so similar to each other,  one could even
  193.  * abstract them all to one routine supplied a parameter determining
  194.  * the nature of the reordering it has to do.
  195.  */
  196. void CryptKey1(int varient, byte const *challenge, struct block *key)
  197. {
  198. static byte perm_challenge[] = {1,3,0,7,5, 2,9,6,4,8};
  199. byte scratch[10];
  200. int i;
  201. for (i = 9; i >= 0; --i)
  202. scratch[i] = challenge[perm_challenge[i]];
  203. engine(varient, scratch,  &key->b[0]);
  204. }
  205. /* This shuffles the bits in varient to make perm_varient such that
  206.  *                4 -> !3
  207.  *                3 ->  4
  208.  * varient bits:  2 ->  0  perm_varient bits
  209.  *                1 ->  2
  210.  *                0 -> !1
  211.  */
  212. void CryptKey2(int varient, byte const *challenge, struct block *key)
  213. {
  214. static byte perm_challenge[] = {6,1,9,3,8, 5,7,4,0,2};
  215. static byte perm_varient[] = {
  216. 0x0a, 0x08, 0x0e, 0x0c, 0x0b, 0x09, 0x0f, 0x0d,
  217. 0x1a, 0x18, 0x1e, 0x1c, 0x1b, 0x19, 0x1f, 0x1d,
  218. 0x02, 0x00, 0x06, 0x04, 0x03, 0x01, 0x07, 0x05,
  219. 0x12, 0x10, 0x16, 0x14, 0x13, 0x11, 0x17, 0x15};
  220. byte scratch[10];
  221. int i;
  222. for (i = 9; i >= 0; --i)
  223. scratch[i] = challenge[perm_challenge[i]];
  224. engine(perm_varient[varient], scratch, &key->b[0]);
  225. }
  226. /* This shuffles the bits in varient to make perm_varient such that
  227.  *                4 ->  0
  228.  *                3 -> !1
  229.  * varient bits:  2 -> !4  perm_varient bits
  230.  *                1 ->  2
  231.  *                0 ->  3
  232.  */
  233. void CryptBusKey(int varient, byte const *challenge, struct block *key)
  234. {
  235. static byte perm_challenge[] = {4,0,3,5,7, 2,8,6,1,9};
  236. static byte perm_varient[] = {
  237. 0x12, 0x1a, 0x16, 0x1e, 0x02, 0x0a, 0x06, 0x0e,
  238. 0x10, 0x18, 0x14, 0x1c, 0x00, 0x08, 0x04, 0x0c,
  239. 0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f,
  240. 0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d};
  241. byte scratch[10];
  242. int i;
  243. for (i = 9; i >= 0; --i)
  244. scratch[i] = challenge[perm_challenge[i]];
  245. engine(perm_varient[varient], scratch, &key->b[0]);
  246. }