⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvbcsa_bs_stream.c

📁 libdvbcsa is a implementation of the DVB Common Scrambling Algorithm
💻 C
字号:
/*    This file is part of libdvbcsa.    libdvbcsa is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published    by the Free Software Foundation; either version 2 of the License,    or (at your option) any later version.    libdvbcsa is distributed in the hope that it will be useful, but    WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    General Public License for more details.    You should have received a copy of the GNU General Public License    along with libdvbcsa; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA    02111-1307 USA    Based on FFdecsa, Copyright (C) 2003-2004  fatih89r    (c) 2006-2008 Alexandre Becoulet <alexandre.becoulet@free.fr>*/#include "dvbcsa/dvbcsa.h"#include "dvbcsa_bs.h"static void DVBCSA_INLINEdvbcsa_bs_stream_sbox1(dvbcsa_bs_word_t fa, dvbcsa_bs_word_t fb,		       dvbcsa_bs_word_t fc, dvbcsa_bs_word_t fd,		       dvbcsa_bs_word_t fe,		       dvbcsa_bs_word_t *sa, dvbcsa_bs_word_t *sb){  dvbcsa_bs_word_t tmp0, tmp1, tmp2, tmp3;  tmp0 = BS_XOR (fa, BS_XOR (fb, BS_NOT (BS_OR (BS_XOR (BS_OR (fa, fb), fc), BS_XOR (fc, fd)))));  tmp1 = BS_XOR (BS_OR (fa, fb), BS_NOT (BS_AND (fc, BS_OR (fa, BS_XOR (fb, fd)))));  tmp2 = BS_XOR (fa, BS_XOR (BS_AND (fb, fd), BS_OR (BS_AND (fa, fd), fc)));  tmp3 = BS_XOR (BS_AND (fa, fc), BS_XOR (fa, BS_OR (BS_AND (fa, fb), fd)));  *sa = BS_XOR (tmp0, BS_AND (fe, tmp1));  *sb = BS_XOR (tmp2, BS_AND (fe, tmp3));}static void DVBCSA_INLINEdvbcsa_bs_stream_sbox2(dvbcsa_bs_word_t fa, dvbcsa_bs_word_t fb,		       dvbcsa_bs_word_t fc, dvbcsa_bs_word_t fd,		       dvbcsa_bs_word_t fe,		       dvbcsa_bs_word_t *sa, dvbcsa_bs_word_t *sb){  dvbcsa_bs_word_t tmp0, tmp1, tmp2, tmp3;  tmp0 = BS_XOR (fa, BS_XOR (BS_AND (fb, BS_OR (fc, fd)), BS_XOR (fc, BS_NOT (fd))));  tmp1 = BS_OR (BS_AND (fa, BS_XOR (fb, fd)), BS_AND (BS_OR (fa, fb), fc));  tmp2 = BS_XOR (BS_AND (fb, fd), BS_OR (BS_AND (fa, fd), BS_XOR (fb, BS_NOT (fc))));  tmp3 = BS_OR (BS_AND (fa, fd), BS_XOR (fa, BS_XOR (fb, BS_AND (fc, fd))));  *sa = BS_XOR (tmp0, BS_AND (fe, tmp1));  *sb = BS_XOR (tmp2, BS_AND (fe, tmp3));}static void DVBCSA_INLINEdvbcsa_bs_stream_sbox3(dvbcsa_bs_word_t fa, dvbcsa_bs_word_t fb,		       dvbcsa_bs_word_t fc, dvbcsa_bs_word_t fd,		       dvbcsa_bs_word_t fe,		       dvbcsa_bs_word_t *sa, dvbcsa_bs_word_t *sb){  dvbcsa_bs_word_t tmp0, tmp1, tmp2;  tmp0 = BS_XOR (fa, BS_XOR (fb, BS_XOR (BS_AND (fc, BS_OR (fa, fd)), fd)));  tmp1 = BS_XOR (BS_AND (fa, fc), BS_OR (BS_XOR (fa, fd), BS_XOR (BS_OR (fb, fc), BS_NOT (fd))));  tmp2 = BS_XOR (fa, BS_XOR (BS_AND (BS_XOR (fb, fc), fd), fc));  *sa = BS_XOR (tmp0, BS_AND (BS_NOT (fe), tmp1));  *sb = BS_XOR (tmp2, fe);}static void DVBCSA_INLINEdvbcsa_bs_stream_sbox4(dvbcsa_bs_word_t fa, dvbcsa_bs_word_t fb,		       dvbcsa_bs_word_t fc, dvbcsa_bs_word_t fd,		       dvbcsa_bs_word_t fe,		       dvbcsa_bs_word_t *sa, dvbcsa_bs_word_t *sb){  dvbcsa_bs_word_t tmp0, tmp1, tmp2;  tmp0 = BS_XOR (fa, BS_OR (BS_AND (fc, BS_XOR (fa, fd)), BS_XOR (fb, BS_OR (fc, BS_NOT (fd)))));  tmp1 = BS_XOR (BS_AND (fa, fb), BS_XOR (fb, BS_XOR (BS_AND (BS_OR (fa, fc), fd), fc)));  tmp2 = BS_XOR (fa, BS_OR (BS_AND (fb, fc), BS_XOR (BS_OR (BS_AND (fa, BS_XOR (fb, fd)), fc), fd)));  *sa = BS_XOR (tmp0, BS_AND (fe, BS_XOR (tmp1, tmp0)));  *sb = BS_XOR (BS_XOR (*sa, tmp2), fe);}static void DVBCSA_INLINEdvbcsa_bs_stream_sbox5(dvbcsa_bs_word_t fa, dvbcsa_bs_word_t fb,		       dvbcsa_bs_word_t fc, dvbcsa_bs_word_t fd,		       dvbcsa_bs_word_t fe,		       dvbcsa_bs_word_t *sa, dvbcsa_bs_word_t *sb){  dvbcsa_bs_word_t tmp0, tmp1, tmp2, tmp3;  tmp0 = BS_OR (BS_XOR (BS_AND (fa, BS_OR (fb, fc)), fb), BS_XOR (BS_OR (BS_XOR (fa, fc), fd), BS_VAL8(ff)));  tmp1 = BS_XOR (fb, BS_AND (BS_XOR (fc, fd), BS_XOR (fc, BS_OR (fb, BS_XOR (fa, fd)))));  tmp2 = BS_XOR (BS_AND (fa, fc), BS_XOR (fb, BS_AND (BS_OR (fb, BS_XOR (fa, fc)), fd)));  tmp3 = BS_OR (BS_AND (BS_XOR (fa, fb), BS_XOR (fc, BS_VAL8(ff))), fd);  *sa = BS_XOR (tmp0, BS_AND (fe, tmp1));  *sb = BS_XOR (tmp2, BS_AND (fe, tmp3));}static void DVBCSA_INLINEdvbcsa_bs_stream_sbox6(dvbcsa_bs_word_t fa, dvbcsa_bs_word_t fb,		       dvbcsa_bs_word_t fc, dvbcsa_bs_word_t fd,		       dvbcsa_bs_word_t fe,		       dvbcsa_bs_word_t *sa, dvbcsa_bs_word_t *sb){  dvbcsa_bs_word_t tmp0, tmp1, tmp2, tmp3;  tmp0 = BS_XOR (BS_AND (BS_AND (fa, fc), fd), BS_XOR (BS_AND (fb, BS_OR (fa, fd)), fc));  tmp1 = BS_NOT (BS_AND (BS_XOR (fa, fc), fd));  tmp2 = BS_XOR (BS_AND (fa, BS_OR (fb, fc)), BS_XOR (fb, BS_OR (BS_AND (fb, fc), fd)));  tmp3 = BS_AND (fc, BS_XOR (BS_AND (fa, BS_XOR (fb, fd)), BS_OR (fb, fd)));  *sa = BS_XOR (tmp0, BS_AND (fe, tmp1));  *sb = BS_XOR (tmp2, BS_AND (fe, tmp3));}static void DVBCSA_INLINEdvbcsa_bs_stream_sbox7(dvbcsa_bs_word_t fa, dvbcsa_bs_word_t fb,		       dvbcsa_bs_word_t fc, dvbcsa_bs_word_t fd,		       dvbcsa_bs_word_t fe,		       dvbcsa_bs_word_t *sa, dvbcsa_bs_word_t *sb){  dvbcsa_bs_word_t tmp0, tmp1, tmp2, tmp3;  tmp0 = BS_XOR (fb, BS_OR (BS_AND (fc, fd), BS_XOR (fa, BS_XOR (fc, fd))));  tmp1 = BS_AND (BS_OR (fb, fd), BS_OR (BS_AND (fa, fc), BS_XOR (fb, BS_XOR (fc, fd))));  tmp2 = BS_XOR (BS_OR (fa, fb), BS_XOR (BS_AND (fc, BS_OR (fb, fd)), fd));  tmp3 = BS_OR (fd, BS_XOR (BS_AND (fa, fc), BS_VAL8(ff)));  *sa = BS_XOR (tmp0, BS_AND (fe, tmp1));  *sb = BS_XOR (tmp2, BS_AND (fe, tmp3));}voiddvbcsa_bs_stream_cipher_batch(const struct dvbcsa_bs_key_s *key,			      const struct dvbcsa_bs_batch_s *pcks,			      unsigned int maxlen){  dvbcsa_bs_word_t A[32 + 10][4];	// 32 because we will move back (virtual shift register)  dvbcsa_bs_word_t B[32 + 10][4];	// 32 because we will move back (virtual shift register)  dvbcsa_bs_word_t X[4];  dvbcsa_bs_word_t Y[4];  dvbcsa_bs_word_t Z[4];  dvbcsa_bs_word_t D[4];  dvbcsa_bs_word_t E[4];  dvbcsa_bs_word_t F[4];  dvbcsa_bs_word_t p;  dvbcsa_bs_word_t q;  dvbcsa_bs_word_t r;  dvbcsa_bs_word_t in1[4];  dvbcsa_bs_word_t in2[4];  dvbcsa_bs_word_t extra_B[4];  dvbcsa_bs_word_t s1a, s1b, s2a, s2b, s3a, s3b, s4a, s4b, s5a, s5b, s6a, s6b, s7a, s7b;  dvbcsa_bs_word_t next_E[4];  dvbcsa_bs_word_t tmp0, tmp1, tmp3, tmp4;  dvbcsa_bs_word_t sb[64];  int h, i, j, k, b;  dvbcsa_bs_stream_transpose_in(pcks, sb);  for (b = 0; b < 4; b++)    {      for (i = 0; i < 8; i++)	{	  // load first 32 bits of ck into A[aboff+0]..A[aboff+7]	  A[i][b] = key->iA_g[i][b];	  // load last  32 bits of ck into B[aboff+0]..B[aboff+7]	  B[i][b] = key->iB_g[i][b];	}      // all other regs = 0      A[8][b] = BS_VAL8(00);      A[9][b] = BS_VAL8(00);      B[8][b] = BS_VAL8(00);      B[9][b] = BS_VAL8(00);      X[b] = BS_VAL8(00);      Y[b] = BS_VAL8(00);      Z[b] = BS_VAL8(00);      D[b] = BS_VAL8(00);      E[b] = BS_VAL8(00);      F[b] = BS_VAL8(00);    }  p = BS_VAL8(00);  q = BS_VAL8(00);  r = BS_VAL8(00);  /* Stream INIT */  for (i = 0; i < 8; i++)    {      for (b = 0; b < 4; b++)	{	  in1[b] = sb[8 * i + 4 + b];	  in2[b] = sb[8 * i + b];	}      for (j = 0; j < 4; j++)	{	  dvbcsa_bs_stream_sbox1(A[0][2], A[5][1], A[6][3], A[8][0], A[3][0], &s1a, &s1b);	  dvbcsa_bs_stream_sbox2(A[2][2], A[5][3], A[6][0], A[8][1], A[1][1], &s2a, &s2b);	  dvbcsa_bs_stream_sbox3(A[1][0], A[4][1], A[4][3], A[5][2], A[0][3], &s3a, &s3b);	  dvbcsa_bs_stream_sbox4(A[0][1], A[1][3], A[3][2], A[7][0], A[2][3], &s4a, &s4b);	  dvbcsa_bs_stream_sbox5(A[3][3], A[5][0], A[7][1], A[8][2], A[4][2], &s5a, &s5b);	  dvbcsa_bs_stream_sbox6(A[3][1], A[4][0], A[6][2], A[8][3], A[2][1], &s6a, &s6b);	  dvbcsa_bs_stream_sbox7(A[2][0], A[6][1], A[7][2], A[7][3], A[1][2], &s7a, &s7b);	  extra_B[3] = BS_XOR (BS_XOR (BS_XOR (B[2][0], B[5][1]), B[6][2]), B[8][3]);	  extra_B[2] = BS_XOR (BS_XOR (BS_XOR (B[5][0], B[7][1]), B[2][3]), B[3][2]);	  extra_B[1] = BS_XOR (BS_XOR (BS_XOR (B[4][3], B[7][2]), B[3][0]), B[4][1]);	  extra_B[0] = BS_XOR (BS_XOR (BS_XOR (B[8][2], B[5][3]), B[2][1]), B[7][0]);	  for (b = 0; b < 4; b++)	    {	      dvbcsa_bs_word_t	A_next;	      A_next = BS_XOR (A[9][b], X[b]);	      A_next = BS_XOR (BS_XOR (A_next, D[b]), ((j % 2) ? in2[b] : in1[b]));	      for (k = 9; k > 0; k--)		A[k][b] = A[k - 1][b];	      A[0][b] = A_next;	    }	  dvbcsa_bs_word_t	B_next[4];	  for (b = 0; b < 4; b++)	    {	      B_next[b] = BS_XOR (BS_XOR (B[6][b], B[9][b]), Y[b]);	      B_next[b] = BS_XOR (B_next[b], ((j % 2) ? in1[b] : in2[b]));	    }	  tmp3 = B_next[3];	  B_next[3] = BS_XOR (B_next[3], BS_AND (BS_XOR (B_next[3], B_next[2]), p));	  B_next[2] = BS_XOR (B_next[2], BS_AND (BS_XOR (B_next[2], B_next[1]), p));	  B_next[1] = BS_XOR (B_next[1], BS_AND (BS_XOR (B_next[1], B_next[0]), p));	  B_next[0] = BS_XOR (B_next[0], BS_AND (BS_XOR (B_next[0], tmp3), p));	  for (b = 0; b < 4; b++)	    {	      for (k = 9; k > 0; k--)		B[k][b] = B[k - 1][b];	      B[0][b] = B_next[b];	    }	  for (b = 0; b < 4; b++)	    D[b] = BS_XOR (BS_XOR (E[b], Z[b]), extra_B[b]);	  for (b = 0; b < 4; b++)	    next_E[b] = F[b];	  tmp0 = BS_XOR (Z[0], E[0]);	  tmp1 = BS_AND (Z[0], E[0]);	  F[0] = BS_XOR (E[0], BS_AND (q, BS_XOR (Z[0], r)));	  tmp3 = BS_AND (tmp0, r);	  tmp4 = BS_OR (tmp1, tmp3);	  tmp0 = BS_XOR (Z[1], E[1]);	  tmp1 = BS_AND (Z[1], E[1]);	  F[1] = BS_XOR (E[1], BS_AND (q, BS_XOR (Z[1], tmp4)));	  tmp3 = BS_AND (tmp0, tmp4);	  tmp4 = BS_OR (tmp1, tmp3);	  tmp0 = BS_XOR (Z[2], E[2]);	  tmp1 = BS_AND (Z[2], E[2]);	  F[2] = BS_XOR (E[2], BS_AND (q, BS_XOR (Z[2], tmp4)));	  tmp3 = BS_AND (tmp0, tmp4);	  tmp4 = BS_OR (tmp1, tmp3);	  tmp0 = BS_XOR (Z[3], E[3]);	  tmp1 = BS_AND (Z[3], E[3]);	  F[3] = BS_XOR (E[3], BS_AND (q, BS_XOR (Z[3], tmp4)));	  tmp3 = BS_AND (tmp0, tmp4);	  r = BS_XOR (r, BS_AND (q, BS_XOR (BS_OR (tmp1, tmp3), r)));	// ultimate carry	  for (b = 0; b < 4; b++)	    E[b] = next_E[b];	  X[0] = s1a;	  X[1] = s2a;	  X[2] = s3b;	  X[3] = s4b;	  Y[0] = s3a;	  Y[1] = s4a;	  Y[2] = s5b;	  Y[3] = s6b;	  Z[0] = s5a;	  Z[1] = s6a;	  Z[2] = s1b;	  Z[3] = s2b;	  p = s7a;	  q = s7b;	}    }  /* Stream GEN */  for (h = 8; h < maxlen; h++)    {      dvbcsa_bs_word_t cb[8];      for (j = 0; j < 4; j++)	{	  dvbcsa_bs_stream_sbox1(A[0][2], A[5][1], A[6][3], A[8][0], A[3][0], &s1a, &s1b);	  dvbcsa_bs_stream_sbox2(A[2][2], A[5][3], A[6][0], A[8][1], A[1][1], &s2a, &s2b);	  dvbcsa_bs_stream_sbox3(A[1][0], A[4][1], A[4][3], A[5][2], A[0][3], &s3a, &s3b);	  dvbcsa_bs_stream_sbox4(A[0][1], A[1][3], A[3][2], A[7][0], A[2][3], &s4a, &s4b);	  dvbcsa_bs_stream_sbox5(A[3][3], A[5][0], A[7][1], A[8][2], A[4][2], &s5a, &s5b);	  dvbcsa_bs_stream_sbox6(A[3][1], A[4][0], A[6][2], A[8][3], A[2][1], &s6a, &s6b);	  dvbcsa_bs_stream_sbox7(A[2][0], A[6][1], A[7][2], A[7][3], A[1][2], &s7a, &s7b);	  // use 4x4 xor to produce extra nibble for T3	  extra_B[3] = BS_XOR (BS_XOR (BS_XOR (B[2][0], B[5][1]), B[6][2]), B[8][3]);	  extra_B[2] = BS_XOR (BS_XOR (BS_XOR (B[5][0], B[7][1]), B[2][3]), B[3][2]);	  extra_B[1] = BS_XOR (BS_XOR (BS_XOR (B[4][3], B[7][2]), B[3][0]), B[4][1]);	  extra_B[0] = BS_XOR (BS_XOR (BS_XOR (B[8][2], B[5][3]), B[2][1]), B[7][0]);	  // T1 = xor all inputs	  // in1, in2, D are only used in T1 during initialisation, not generation	  for (b = 0; b < 4; b++)	    {	      dvbcsa_bs_word_t	A_next;	      A_next = BS_XOR (A[9][b], X[b]);	      for (k = 9; k > 0; k--)		A[k][b] = A[k - 1][b];	      A[0][b] = A_next;	    }	  dvbcsa_bs_word_t	B_next[4];	  // T2 =  xor all inputs	  // in1, in2 are only used in T1 during initialisation, not generation	  // if p=0, use this, if p=1, rotate the result left	  for (b = 0; b < 4; b++)	    B_next[b] = BS_XOR (BS_XOR (B[6][b], B[9][b]), Y[b]);	  // if p=1, rotate left (yes, this is what we're doing)	  tmp3 = B_next[3];	  B_next[3] = BS_XOR (B_next[3], BS_AND (BS_XOR (B_next[3], B_next[2]), p));	  B_next[2] = BS_XOR (B_next[2], BS_AND (BS_XOR (B_next[2], B_next[1]), p));	  B_next[1] = BS_XOR (B_next[1], BS_AND (BS_XOR (B_next[1], B_next[0]), p));	  B_next[0] = BS_XOR (B_next[0], BS_AND (BS_XOR (B_next[0], tmp3), p));	  for (b = 0; b < 4; b++)	    {	      for (k = 9; k > 0; k--)		B[k][b] = B[k - 1][b];	      B[0][b] = B_next[b];	    }	  // T3 = xor all inputs	  for (b = 0; b < 4; b++)	    D[b] = BS_XOR (BS_XOR (E[b], Z[b]), extra_B[b]);	  // T4 = sum, carry of Z + E + r	  for (b = 0; b < 4; b++)	    next_E[b] = F[b];	  tmp0 = BS_XOR (Z[0], E[0]);	  tmp1 = BS_AND (Z[0], E[0]);	  F[0] = BS_XOR (E[0], BS_AND (q, BS_XOR (Z[0], r)));	  tmp3 = BS_AND (tmp0, r);	  tmp4 = BS_OR (tmp1, tmp3);	  tmp0 = BS_XOR (Z[1], E[1]);	  tmp1 = BS_AND (Z[1], E[1]);	  F[1] = BS_XOR (E[1], BS_AND (q, BS_XOR (Z[1], tmp4)));	  tmp3 = BS_AND (tmp0, tmp4);	  tmp4 = BS_OR (tmp1, tmp3);	  tmp0 = BS_XOR (Z[2], E[2]);	  tmp1 = BS_AND (Z[2], E[2]);	  F[2] = BS_XOR (E[2], BS_AND (q, BS_XOR (Z[2], tmp4)));	  tmp3 = BS_AND (tmp0, tmp4);	  tmp4 = BS_OR (tmp1, tmp3);	  tmp0 = BS_XOR (Z[3], E[3]);	  tmp1 = BS_AND (Z[3], E[3]);	  F[3] = BS_XOR (E[3], BS_AND (q, BS_XOR (Z[3], tmp4)));	  tmp3 = BS_AND (tmp0, tmp4);	  r = BS_XOR (r, BS_AND (q, BS_XOR (BS_OR (tmp1, tmp3), r)));	// ultimate carry	  for (b = 0; b < 4; b++)	    E[b] = next_E[b];	  X[0] = s1a;	  X[1] = s2a;	  X[2] = s3b;	  X[3] = s4b;	  Y[0] = s3a;	  Y[1] = s4a;	  Y[2] = s5b;	  Y[3] = s6b;	  Z[0] = s5a;	  Z[1] = s6a;	  Z[2] = s1b;	  Z[3] = s2b;	  p = s7a;	  q = s7b;	  // require 4 loops per output byte	  // 2 output bits are a function of the 4 bits of D	  // xor 2 by 2	  cb[7 - 2 * j] = BS_XOR (D[2], D[3]);	  cb[6 - 2 * j] = BS_XOR (D[0], D[1]);	}				// EXTERNAL LOOP      ////////////////////////////////////////////////////////////////////////////////      dvbcsa_bs_stream_transpose_out(pcks, h, cb);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -