demux: mp4: avoid audio cuts on seek
[vlc.git] / modules / mux / mpeg / csa.c
blob19c2d6ad9381dafb18ec06c9dbc5931b9c9b44d3
1 /*****************************************************************************
2 * libcsa.c: CSA scrambler/descrambler
3 *****************************************************************************
4 * Copyright (C) 2004-2005 Laurent Aimar
5 * Copyright (C) the deCSA authors
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Jean-Paul Saman <jpsaman #_at_# m2x.nl>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
29 #include <vlc_common.h>
31 #include "csa.h"
33 struct csa_t
35 /* odd and even keys */
36 uint8_t o_ck[8];
37 uint8_t e_ck[8];
39 uint8_t o_kk[57];
40 uint8_t e_kk[57];
42 /* cypher state */
43 int A[11];
44 int B[11];
45 int X, Y, Z;
46 int D, E, F;
47 int p, q, r;
49 bool use_odd;
52 static void csa_ComputeKey( uint8_t kk[57], uint8_t ck[8] );
54 static void csa_StreamCypher( csa_t *c, int b_init, uint8_t *ck, uint8_t *sb, uint8_t *cb );
56 static void csa_BlockDecypher( uint8_t kk[57], uint8_t ib[8], uint8_t bd[8] );
57 static void csa_BlockCypher( uint8_t kk[57], uint8_t bd[8], uint8_t ib[8] );
59 /*****************************************************************************
60 * csa_New:
61 *****************************************************************************/
62 csa_t *csa_New( void )
64 return calloc( 1, sizeof( csa_t ) );
67 /*****************************************************************************
68 * csa_Delete:
69 *****************************************************************************/
70 void csa_Delete( csa_t *c )
72 free( c );
75 /*****************************************************************************
76 * csa_SetCW:
77 *****************************************************************************/
78 int csa_SetCW( vlc_object_t *p_caller, csa_t *c, char *psz_ck, bool set_odd )
80 if ( !c )
82 msg_Dbg( p_caller, "no CSA found" );
83 return VLC_ENOOBJ;
85 /* skip 0x */
86 if( psz_ck[0] == '0' && ( psz_ck[1] == 'x' || psz_ck[1] == 'X' ) )
88 psz_ck += 2;
90 if( strlen( psz_ck ) != 16 )
92 msg_Warn( p_caller, "invalid csa ck (it must be 16 chars long)" );
93 return VLC_EBADVAR;
95 else
97 uint64_t i_ck = strtoull( psz_ck, NULL, 16 );
98 uint8_t ck[8];
99 int i;
101 for( i = 0; i < 8; i++ )
103 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
105 #ifndef TS_NO_CSA_CK_MSG
106 msg_Dbg( p_caller, "using CSA (de)scrambling with %s "
107 "key=%x:%x:%x:%x:%x:%x:%x:%x", set_odd ? "odd" : "even",
108 ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
109 #endif
110 if( set_odd )
112 memcpy( c->o_ck, ck, 8 );
113 csa_ComputeKey( c->o_kk, ck );
115 else
117 memcpy( c->e_ck , ck, 8 );
118 csa_ComputeKey( c->e_kk , ck );
120 return VLC_SUCCESS;
124 /*****************************************************************************
125 * csa_UseKey:
126 *****************************************************************************/
127 int csa_UseKey( vlc_object_t *p_caller, csa_t *c, bool use_odd )
129 if ( !c ) return VLC_ENOOBJ;
130 c->use_odd = use_odd;
131 #ifndef TS_NO_CSA_CK_MSG
132 msg_Dbg( p_caller, "using the %s key for scrambling",
133 use_odd ? "odd" : "even" );
134 #endif
135 return VLC_SUCCESS;
138 /*****************************************************************************
139 * csa_Decrypt:
140 *****************************************************************************/
141 void csa_Decrypt( csa_t *c, uint8_t *pkt, int i_pkt_size )
143 uint8_t *ck;
144 uint8_t *kk;
146 uint8_t ib[8], stream[8], block[8];
148 int i_hdr, i_residue;
149 int i, j, n;
151 /* transport scrambling control */
152 if( (pkt[3]&0x80) == 0 )
154 /* not scrambled */
155 return;
157 if( pkt[3]&0x40 )
159 ck = c->o_ck;
160 kk = c->o_kk;
162 else
164 ck = c->e_ck;
165 kk = c->e_kk;
168 /* clear transport scrambling control */
169 pkt[3] &= 0x3f;
171 i_hdr = 4;
172 if( pkt[3]&0x20 )
174 /* skip adaption field */
175 i_hdr += pkt[4] + 1;
178 if( 188 - i_hdr < 8 )
179 return;
181 /* init csa state */
182 csa_StreamCypher( c, 1, ck, &pkt[i_hdr], ib );
184 /* */
185 n = (i_pkt_size - i_hdr) / 8;
186 if( n < 0 )
187 return;
189 i_residue = (i_pkt_size - i_hdr) % 8;
190 for( i = 1; i < n + 1; i++ )
192 csa_BlockDecypher( kk, ib, block );
193 if( i != n )
195 csa_StreamCypher( c, 0, ck, NULL, stream );
196 for( j = 0; j < 8; j++ )
198 /* xor ib with stream */
199 ib[j] = pkt[i_hdr+8*i+j] ^ stream[j];
202 else
204 /* last block */
205 for( j = 0; j < 8; j++ )
207 ib[j] = 0;
210 /* xor ib with block */
211 for( j = 0; j < 8; j++ )
213 pkt[i_hdr+8*(i-1)+j] = ib[j] ^ block[j];
217 if( i_residue > 0 )
219 csa_StreamCypher( c, 0, ck, NULL, stream );
220 for( j = 0; j < i_residue; j++ )
222 pkt[i_pkt_size - i_residue + j] ^= stream[j];
227 /*****************************************************************************
228 * csa_Encrypt:
229 *****************************************************************************/
230 void csa_Encrypt( csa_t *c, uint8_t *pkt, int i_pkt_size )
232 uint8_t *ck;
233 uint8_t *kk;
235 int i, j;
236 int i_hdr = 4; /* hdr len */
237 uint8_t ib[184/8+2][8], stream[8], block[8];
238 int n, i_residue;
240 /* set transport scrambling control */
241 pkt[3] |= 0x80;
243 if( c->use_odd )
245 pkt[3] |= 0x40;
246 ck = c->o_ck;
247 kk = c->o_kk;
249 else
251 ck = c->e_ck;
252 kk = c->e_kk;
255 /* hdr len */
256 i_hdr = 4;
257 if( pkt[3]&0x20 )
259 /* skip adaption field */
260 i_hdr += pkt[4] + 1;
262 n = (i_pkt_size - i_hdr) / 8;
263 i_residue = (i_pkt_size - i_hdr) % 8;
265 if( n <= 0 )
267 pkt[3] &= 0x3f;
268 return;
271 /* */
272 for( i = 0; i < 8; i++ )
274 ib[n+1][i] = 0;
276 for( i = n; i > 0; i-- )
278 for( j = 0; j < 8; j++ )
280 block[j] = pkt[i_hdr+8*(i-1)+j] ^ib[i+1][j];
282 csa_BlockCypher( kk, block, ib[i] );
285 /* init csa state */
286 csa_StreamCypher( c, 1, ck, ib[1], stream );
288 for( i = 0; i < 8; i++ )
290 pkt[i_hdr+i] = ib[1][i];
292 for( i = 2; i < n+1; i++ )
294 csa_StreamCypher( c, 0, ck, NULL, stream );
295 for( j = 0; j < 8; j++ )
297 pkt[i_hdr+8*(i-1)+j] = ib[i][j] ^ stream[j];
300 if( i_residue > 0 )
302 csa_StreamCypher( c, 0, ck, NULL, stream );
303 for( j = 0; j < i_residue; j++ )
305 pkt[i_pkt_size - i_residue + j] ^= stream[j];
310 /*****************************************************************************
311 * Divers
312 *****************************************************************************/
313 static const uint8_t key_perm[0x40] =
315 0x12,0x24,0x09,0x07,0x2A,0x31,0x1D,0x15,0x1C,0x36,0x3E,0x32,0x13,0x21,0x3B,0x40,
316 0x18,0x14,0x25,0x27,0x02,0x35,0x1B,0x01,0x22,0x04,0x0D,0x0E,0x39,0x28,0x1A,0x29,
317 0x33,0x23,0x34,0x0C,0x16,0x30,0x1E,0x3A,0x2D,0x1F,0x08,0x19,0x17,0x2F,0x3D,0x11,
318 0x3C,0x05,0x38,0x2B,0x0B,0x06,0x0A,0x2C,0x20,0x3F,0x2E,0x0F,0x03,0x26,0x10,0x37,
321 static void csa_ComputeKey( uint8_t kk[57], uint8_t ck[8] )
323 int i,j,k;
324 int bit[64];
325 int newbit[64];
326 int kb[8][9];
328 /* from a cw create 56 key bytes, here kk[1..56] */
330 /* load ck into kb[7][1..8] */
331 for( i = 0; i < 8; i++ )
333 kb[7][i+1] = ck[i];
336 /* calculate all kb[6..1][*] */
337 for( i = 0; i < 7; i++ )
339 /* do a 64 bit perm on kb */
340 for( j = 0; j < 8; j++ )
342 for( k = 0; k < 8; k++ )
344 bit[j*8+k] = (kb[7-i][1+j] >> (7-k)) & 1;
345 newbit[key_perm[j*8+k]-1] = bit[j*8+k];
348 for( j = 0; j < 8; j++ )
350 kb[6-i][1+j] = 0;
351 for( k = 0; k < 8; k++ )
353 kb[6-i][1+j] |= newbit[j*8+k] << (7-k);
358 /* xor to give kk */
359 for( i = 0; i < 7; i++ )
361 for( j = 0; j < 8; j++ )
363 kk[1+i*8+j] = kb[1+i][1+j] ^ i;
369 static const int sbox1[0x20] = {2,0,1,1,2,3,3,0, 3,2,2,0,1,1,0,3, 0,3,3,0,2,2,1,1, 2,2,0,3,1,1,3,0};
370 static const int sbox2[0x20] = {3,1,0,2,2,3,3,0, 1,3,2,1,0,0,1,2, 3,1,0,3,3,2,0,2, 0,0,1,2,2,1,3,1};
371 static const int sbox3[0x20] = {2,0,1,2,2,3,3,1, 1,1,0,3,3,0,2,0, 1,3,0,1,3,0,2,2, 2,0,1,2,0,3,3,1};
372 static const int sbox4[0x20] = {3,1,2,3,0,2,1,2, 1,2,0,1,3,0,0,3, 1,0,3,1,2,3,0,3, 0,3,2,0,1,2,2,1};
373 static const int sbox5[0x20] = {2,0,0,1,3,2,3,2, 0,1,3,3,1,0,2,1, 2,3,2,0,0,3,1,1, 1,0,3,2,3,1,0,2};
374 static const int sbox6[0x20] = {0,1,2,3,1,2,2,0, 0,1,3,0,2,3,1,3, 2,3,0,2,3,0,1,1, 2,1,1,2,0,3,3,0};
375 static const int sbox7[0x20] = {0,3,2,2,3,0,0,1, 3,0,1,3,1,2,2,1, 1,0,3,3,0,1,1,2, 2,3,1,0,2,3,0,2};
377 static void csa_StreamCypher( csa_t *c, int b_init, uint8_t *ck, uint8_t *sb, uint8_t *cb )
379 int i,j, k;
380 int extra_B;
381 int s1,s2,s3,s4,s5,s6,s7;
382 int next_A1;
383 int next_B1;
384 int next_E;
386 if( b_init )
388 // load first 32 bits of CK into A[1]..A[8]
389 // load last 32 bits of CK into B[1]..B[8]
390 // all other regs = 0
391 for( i = 0; i < 4; i++ )
393 c->A[1+2*i+0] = ( ck[i] >> 4 )&0x0f;
394 c->A[1+2*i+1] = ( ck[i] >> 0 )&0x0f;
396 c->B[1+2*i+0] = ( ck[4+i] >> 4 )&0x0f;
397 c->B[1+2*i+1] = ( ck[4+i] >> 0 )&0x0f;
400 c->A[9] = c->A[10] = 0;
401 c->B[9] = c->B[10] = 0;
403 c->X = c->Y = c->Z = 0;
404 c->D = c->E = c->F = 0;
405 c->p = c->q = c->r = 0;
408 // 8 bytes per operation
409 for( i = 0; i < 8; i++ )
411 int op = 0;
412 int in1 = 0; /* gcc warn */
413 int in2 = 0;
415 if( b_init )
417 in1 = ( sb[i] >> 4 )&0x0f;
418 in2 = ( sb[i] >> 0 )&0x0f;
421 // 2 bits per iteration
422 for( j = 0; j < 4; j++ )
424 // from A[1]..A[10], 35 bits are selected as inputs to 7 s-boxes
425 // 5 bits input per s-box, 2 bits output per s-box
426 s1 = sbox1[ (((c->A[4]>>0)&1)<<4) | (((c->A[1]>>2)&1)<<3) | (((c->A[6]>>1)&1)<<2) | (((c->A[7]>>3)&1)<<1) | (((c->A[9]>>0)&1)<<0) ];
427 s2 = sbox2[ (((c->A[2]>>1)&1)<<4) | (((c->A[3]>>2)&1)<<3) | (((c->A[6]>>3)&1)<<2) | (((c->A[7]>>0)&1)<<1) | (((c->A[9]>>1)&1)<<0) ];
428 s3 = sbox3[ (((c->A[1]>>3)&1)<<4) | (((c->A[2]>>0)&1)<<3) | (((c->A[5]>>1)&1)<<2) | (((c->A[5]>>3)&1)<<1) | (((c->A[6]>>2)&1)<<0) ];
429 s4 = sbox4[ (((c->A[3]>>3)&1)<<4) | (((c->A[1]>>1)&1)<<3) | (((c->A[2]>>3)&1)<<2) | (((c->A[4]>>2)&1)<<1) | (((c->A[8]>>0)&1)<<0) ];
430 s5 = sbox5[ (((c->A[5]>>2)&1)<<4) | (((c->A[4]>>3)&1)<<3) | (((c->A[6]>>0)&1)<<2) | (((c->A[8]>>1)&1)<<1) | (((c->A[9]>>2)&1)<<0) ];
431 s6 = sbox6[ (((c->A[3]>>1)&1)<<4) | (((c->A[4]>>1)&1)<<3) | (((c->A[5]>>0)&1)<<2) | (((c->A[7]>>2)&1)<<1) | (((c->A[9]>>3)&1)<<0) ];
432 s7 = sbox7[ (((c->A[2]>>2)&1)<<4) | (((c->A[3]>>0)&1)<<3) | (((c->A[7]>>1)&1)<<2) | (((c->A[8]>>2)&1)<<1) | (((c->A[8]>>3)&1)<<0) ];
434 /* use 4x4 xor to produce extra nibble for T3 */
435 extra_B = ( ((c->B[3]&1)<<3) ^ ((c->B[6]&2)<<2) ^ ((c->B[7]&4)<<1) ^ ((c->B[9]&8)>>0) ) |
436 ( ((c->B[6]&1)<<2) ^ ((c->B[8]&2)<<1) ^ ((c->B[3]&8)>>1) ^ ((c->B[4]&4)>>0) ) |
437 ( ((c->B[5]&8)>>2) ^ ((c->B[8]&4)>>1) ^ ((c->B[4]&1)<<1) ^ ((c->B[5]&2)>>0) ) |
438 ( ((c->B[9]&4)>>2) ^ ((c->B[6]&8)>>3) ^ ((c->B[3]&2)>>1) ^ ((c->B[8]&1)>>0) ) ;
440 // T1 = xor all inputs
441 // in1,in2, D are only used in T1 during initialisation, not generation
442 next_A1 = c->A[10] ^ c->X;
443 if( b_init ) next_A1 = next_A1 ^ c->D ^ ((j % 2) ? in2 : in1);
445 // T2 = xor all inputs
446 // in1,in2 are only used in T1 during initialisation, not generation
447 // if p=0, use this, if p=1, rotate the result left
448 next_B1 = c->B[7] ^ c->B[10] ^ c->Y;
449 if( b_init) next_B1 = next_B1 ^ ((j % 2) ? in1 : in2);
451 // if p=1, rotate left
452 if( c->p ) next_B1 = ( (next_B1 << 1) | ((next_B1 >> 3) & 1) ) & 0xf;
454 // T3 = xor all inputs
455 c->D = c->E ^ c->Z ^ extra_B;
457 // T4 = sum, carry of Z + E + r
458 next_E = c->F;
459 if( c->q )
461 c->F = c->Z + c->E + c->r;
462 // r is the carry
463 c->r = (c->F >> 4) & 1;
464 c->F = c->F & 0x0f;
466 else
468 c->F = c->E;
470 c->E = next_E;
472 for( k = 10; k > 1; k-- )
474 c->A[k] = c->A[k-1];
475 c->B[k] = c->B[k-1];
477 c->A[1] = next_A1;
478 c->B[1] = next_B1;
480 c->X = ((s4&1)<<3) | ((s3&1)<<2) | (s2&2) | ((s1&2)>>1);
481 c->Y = ((s6&1)<<3) | ((s5&1)<<2) | (s4&2) | ((s3&2)>>1);
482 c->Z = ((s2&1)<<3) | ((s1&1)<<2) | (s6&2) | ((s5&2)>>1);
483 c->p = (s7&2)>>1;
484 c->q = (s7&1);
486 // require 4 loops per output byte
487 // 2 output bits are a function of the 4 bits of D
488 // xor 2 by 2
489 op = (op << 2)^ ( (((c->D^(c->D>>1))>>1)&2) | ((c->D^(c->D>>1))&1) );
491 // return input data during init
492 cb[i] = b_init ? sb[i] : op;
497 // block - sbox
498 static const uint8_t block_sbox[256] =
500 0x3A,0xEA,0x68,0xFE,0x33,0xE9,0x88,0x1A,0x83,0xCF,0xE1,0x7F,0xBA,0xE2,0x38,0x12,
501 0xE8,0x27,0x61,0x95,0x0C,0x36,0xE5,0x70,0xA2,0x06,0x82,0x7C,0x17,0xA3,0x26,0x49,
502 0xBE,0x7A,0x6D,0x47,0xC1,0x51,0x8F,0xF3,0xCC,0x5B,0x67,0xBD,0xCD,0x18,0x08,0xC9,
503 0xFF,0x69,0xEF,0x03,0x4E,0x48,0x4A,0x84,0x3F,0xB4,0x10,0x04,0xDC,0xF5,0x5C,0xC6,
504 0x16,0xAB,0xAC,0x4C,0xF1,0x6A,0x2F,0x3C,0x3B,0xD4,0xD5,0x94,0xD0,0xC4,0x63,0x62,
505 0x71,0xA1,0xF9,0x4F,0x2E,0xAA,0xC5,0x56,0xE3,0x39,0x93,0xCE,0x65,0x64,0xE4,0x58,
506 0x6C,0x19,0x42,0x79,0xDD,0xEE,0x96,0xF6,0x8A,0xEC,0x1E,0x85,0x53,0x45,0xDE,0xBB,
507 0x7E,0x0A,0x9A,0x13,0x2A,0x9D,0xC2,0x5E,0x5A,0x1F,0x32,0x35,0x9C,0xA8,0x73,0x30,
509 0x29,0x3D,0xE7,0x92,0x87,0x1B,0x2B,0x4B,0xA5,0x57,0x97,0x40,0x15,0xE6,0xBC,0x0E,
510 0xEB,0xC3,0x34,0x2D,0xB8,0x44,0x25,0xA4,0x1C,0xC7,0x23,0xED,0x90,0x6E,0x50,0x00,
511 0x99,0x9E,0x4D,0xD9,0xDA,0x8D,0x6F,0x5F,0x3E,0xD7,0x21,0x74,0x86,0xDF,0x6B,0x05,
512 0x8E,0x5D,0x37,0x11,0xD2,0x28,0x75,0xD6,0xA7,0x77,0x24,0xBF,0xF0,0xB0,0x02,0xB7,
513 0xF8,0xFC,0x81,0x09,0xB1,0x01,0x76,0x91,0x7D,0x0F,0xC8,0xA0,0xF2,0xCB,0x78,0x60,
514 0xD1,0xF7,0xE0,0xB5,0x98,0x22,0xB3,0x20,0x1D,0xA6,0xDB,0x7B,0x59,0x9F,0xAE,0x31,
515 0xFB,0xD3,0xB6,0xCA,0x43,0x72,0x07,0xF4,0xD8,0x41,0x14,0x55,0x0D,0x54,0x8B,0xB9,
516 0xAD,0x46,0x0B,0xAF,0x80,0x52,0x2C,0xFA,0x8C,0x89,0x66,0xFD,0xB2,0xA9,0x9B,0xC0,
519 // block - perm
520 static const uint8_t block_perm[256] =
522 0x00,0x02,0x80,0x82,0x20,0x22,0xA0,0xA2, 0x10,0x12,0x90,0x92,0x30,0x32,0xB0,0xB2,
523 0x04,0x06,0x84,0x86,0x24,0x26,0xA4,0xA6, 0x14,0x16,0x94,0x96,0x34,0x36,0xB4,0xB6,
524 0x40,0x42,0xC0,0xC2,0x60,0x62,0xE0,0xE2, 0x50,0x52,0xD0,0xD2,0x70,0x72,0xF0,0xF2,
525 0x44,0x46,0xC4,0xC6,0x64,0x66,0xE4,0xE6, 0x54,0x56,0xD4,0xD6,0x74,0x76,0xF4,0xF6,
526 0x01,0x03,0x81,0x83,0x21,0x23,0xA1,0xA3, 0x11,0x13,0x91,0x93,0x31,0x33,0xB1,0xB3,
527 0x05,0x07,0x85,0x87,0x25,0x27,0xA5,0xA7, 0x15,0x17,0x95,0x97,0x35,0x37,0xB5,0xB7,
528 0x41,0x43,0xC1,0xC3,0x61,0x63,0xE1,0xE3, 0x51,0x53,0xD1,0xD3,0x71,0x73,0xF1,0xF3,
529 0x45,0x47,0xC5,0xC7,0x65,0x67,0xE5,0xE7, 0x55,0x57,0xD5,0xD7,0x75,0x77,0xF5,0xF7,
531 0x08,0x0A,0x88,0x8A,0x28,0x2A,0xA8,0xAA, 0x18,0x1A,0x98,0x9A,0x38,0x3A,0xB8,0xBA,
532 0x0C,0x0E,0x8C,0x8E,0x2C,0x2E,0xAC,0xAE, 0x1C,0x1E,0x9C,0x9E,0x3C,0x3E,0xBC,0xBE,
533 0x48,0x4A,0xC8,0xCA,0x68,0x6A,0xE8,0xEA, 0x58,0x5A,0xD8,0xDA,0x78,0x7A,0xF8,0xFA,
534 0x4C,0x4E,0xCC,0xCE,0x6C,0x6E,0xEC,0xEE, 0x5C,0x5E,0xDC,0xDE,0x7C,0x7E,0xFC,0xFE,
535 0x09,0x0B,0x89,0x8B,0x29,0x2B,0xA9,0xAB, 0x19,0x1B,0x99,0x9B,0x39,0x3B,0xB9,0xBB,
536 0x0D,0x0F,0x8D,0x8F,0x2D,0x2F,0xAD,0xAF, 0x1D,0x1F,0x9D,0x9F,0x3D,0x3F,0xBD,0xBF,
537 0x49,0x4B,0xC9,0xCB,0x69,0x6B,0xE9,0xEB, 0x59,0x5B,0xD9,0xDB,0x79,0x7B,0xF9,0xFB,
538 0x4D,0x4F,0xCD,0xCF,0x6D,0x6F,0xED,0xEF, 0x5D,0x5F,0xDD,0xDF,0x7D,0x7F,0xFD,0xFF,
541 static void csa_BlockDecypher( uint8_t kk[57], uint8_t ib[8], uint8_t bd[8] )
543 int i;
544 int perm_out;
545 int R[9];
546 int next_R8;
548 for( i = 0; i < 8; i++ )
550 R[i+1] = ib[i];
553 // loop over kk[56]..kk[1]
554 for( i = 56; i > 0; i-- )
556 const int sbox_out = block_sbox[ kk[i]^R[7] ];
557 perm_out = block_perm[sbox_out];
559 next_R8 = R[7];
560 R[7] = R[6] ^ perm_out;
561 R[6] = R[5];
562 R[5] = R[4] ^ R[8] ^ sbox_out;
563 R[4] = R[3] ^ R[8] ^ sbox_out;
564 R[3] = R[2] ^ R[8] ^ sbox_out;
565 R[2] = R[1];
566 R[1] = R[8] ^ sbox_out;
568 R[8] = next_R8;
571 for( i = 0; i < 8; i++ )
573 bd[i] = R[i+1];
577 static void csa_BlockCypher( uint8_t kk[57], uint8_t bd[8], uint8_t ib[8] )
579 int i;
580 int perm_out;
581 int R[9];
582 int next_R1;
584 for( i = 0; i < 8; i++ )
586 R[i+1] = bd[i];
589 // loop over kk[1]..kk[56]
590 for( i = 1; i <= 56; i++ )
592 const int sbox_out = block_sbox[ kk[i]^R[8] ];
593 perm_out = block_perm[sbox_out];
595 next_R1 = R[2];
596 R[2] = R[3] ^ R[1];
597 R[3] = R[4] ^ R[1];
598 R[4] = R[5] ^ R[1];
599 R[5] = R[6];
600 R[6] = R[7] ^ perm_out;
601 R[7] = R[8];
602 R[8] = R[1] ^ sbox_out;
604 R[1] = next_R1;
607 for( i = 0; i < 8; i++ )
609 ib[i] = R[i+1];