static AYCW_INLINE void aycw__vInitShiftRegister(dvbcsa_bs_word_t * BS_key, aycw_tstRegister * stRegister) { uint8 i; /****** A & B init ********************/ /* set everything outside bit 32 to zero */ /* load A and B into A_BS and B_BS */ for (i = 0; i < 32; i+=8) { stRegister->A_BS[i + 0] = BS_key[i + 4]; stRegister->A_BS[i + 1] = BS_key[i + 5]; stRegister->A_BS[i + 2] = BS_key[i + 6]; stRegister->A_BS[i + 3] = BS_key[i + 7]; stRegister->A_BS[i + 4] = BS_key[i + 0]; stRegister->A_BS[i + 5] = BS_key[i + 1]; stRegister->A_BS[i + 6] = BS_key[i + 2]; stRegister->A_BS[i + 7] = BS_key[i + 3]; stRegister->B_BS[i + 0] = BS_key[i + 4 + 32]; stRegister->B_BS[i + 1] = BS_key[i + 5 + 32]; stRegister->B_BS[i + 2] = BS_key[i + 6 + 32]; stRegister->B_BS[i + 3] = BS_key[i + 7 + 32]; stRegister->B_BS[i + 4] = BS_key[i + 0 + 32]; stRegister->B_BS[i + 5] = BS_key[i + 1 + 32]; stRegister->B_BS[i + 6] = BS_key[i + 2 + 32]; stRegister->B_BS[i + 7] = BS_key[i + 3 + 32]; } for (/*i = 32*/; i < 40; i++) { stRegister->A_BS[i] = BS_VAL8(00); stRegister->B_BS[i] = BS_VAL8(00); } }
AYCW_INLINE dvbcsa_bs_word_t aycw__BitExpandOfByteToBsWord(const uint8 *u8ByteToExpand, const uint8 u8Byte, const uint8 u8Bit) { dvbcsa_bs_word_t ret; if ((0x1 << u8Bit) & u8ByteToExpand[u8Byte]) { ret = BS_VAL8(FF); } else { ret = BS_VAL8(00); } return ret; }
void dvbcsa_bs_key_set (const dvbcsa_cw_t cw, struct dvbcsa_bs_key_s *key) { dvbcsa_keys_t kk; int i; /* precalculations for stream */ uint64_t ck = dvbcsa_load_le64(cw); for (i = 0; i < DVBCSA_CWBITS_SIZE; i++) key->stream[i] = (ck >> (i^4)) & 1 ? BS_VAL8(ff) : BS_VAL8(00); /* precalculations for block */ dvbcsa_key_schedule_block(cw, kk); for (i = 0; i < DVBCSA_KEYSBUFF_SIZE; i++) { #if BS_BATCH_SIZE == 32 *(uint32_t*)(key->block + i) = kk[i] * 0x01010101; #elif BS_BATCH_SIZE == 64 *(uint64_t*)(key->block + i) = kk[i] * 0x0101010101010101ULL; #elif BS_BATCH_SIZE > 64 && BS_BATCH_SIZE % 64 == 0 uint64_t v = kk[i] * 0x0101010101010101ULL; int j; for (j = 0; j < BS_BATCH_BYTES / 8; j++) *((uint64_t*)(key->block + i) + j) = v; #else # error #endif } }
static AYCW_INLINE void aycw_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)); }
AYCW_INLINE void aycw__ShiftRegisterLeft(dvbcsa_bs_word_t * RegisterValue, uint8 u8ShiftValue, uint8 u8Arraysize) { uint8 i; /* move first */ for ( i = (u8Arraysize-1); i >= u8ShiftValue; i--) { RegisterValue[i] = RegisterValue[i-u8ShiftValue]; } /* set rest to zero... */ for ( i = 0; i < u8ShiftValue; i++) { RegisterValue[i] = BS_VAL8(00); } }
static void DVBCSA_INLINE dvbcsa_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)); }
void aycw_key_transpose(const uint8 key[BS_BATCH_SIZE][8], dvbcsa_bs_word_t *row) { unsigned int i, j, k; // copy key 0 and key 1 to to row 0 // copy key 2 and key 3 to to row 1 // copy key 126 and key 127 to row 63 for (k = 0; k < 64; k++) { row[k] = BS_VAL( acyw_load_le32(&key[(k + 64)][4]), acyw_load_le32(&key[(k + 64)][0]), acyw_load_le32(&key[(k + 0)][4]), acyw_load_le32(&key[(k + 0)][0])); } for (i = 0; i < 32; i++) { dvbcsa_bs_word_t t, b; t = row[i]; b = row[32 + i]; #ifdef HAVE_X64_COMPILER row[i] = BS_OR(BS_AND(t, BS_VAL64(00000000ffffffff)), BS_SHL8(BS_AND(b, BS_VAL64(00000000ffffffff)), 4)); row[32 + i] = BS_OR(BS_AND(b, BS_VAL64(ffffffff00000000)), BS_SHR8(BS_AND(t, BS_VAL64(ffffffff00000000)), 4)); #else row[i] = BS_OR(BS_AND(t, BS_VAL(0x00000000, 0xffffffff, 0x00000000, 0xffffffff)), BS_SHL8(BS_AND(b, BS_VAL(0x00000000, 0xffffffff, 0x00000000, 0xffffffff)), 4)); row[32 + i] = BS_OR(BS_AND(b, BS_VAL(0xffffffff, 0x00000000, 0xffffffff, 0x00000000)), BS_SHR8(BS_AND(t, BS_VAL(0xffffffff, 0x00000000, 0xffffffff, 0x00000000)), 4)); #endif } for (j = 0; j < 64; j += 32) { dvbcsa_bs_word_t t, b; for (i = 0; i < 16; i++) { t = row[j + i]; b = row[j + 16 + i]; row[j + i] = BS_OR(BS_AND(t, BS_VAL32(0000ffff)), BS_SHL8(BS_AND(b, BS_VAL32(0000ffff)), 2)); row[j + 16 + i] = BS_OR(BS_AND(b, BS_VAL32(ffff0000)), BS_SHR8(BS_AND(t, BS_VAL32(ffff0000)), 2)); } } for (j = 0; j < 64; j += 16) { dvbcsa_bs_word_t t, b; for (i = 0; i < 8; i++) { t = row[j + i]; b = row[j + 8 + i]; row[j + i] = BS_OR(BS_AND(t, BS_VAL16(00ff)), BS_SHL8(BS_AND(b, BS_VAL16(00ff)), 1)); row[j + 8 + i] = BS_OR(BS_AND(b, BS_VAL16(ff00)), BS_SHR8(BS_AND(t, BS_VAL16(ff00)), 1)); } } for (j = 0; j < 64; j += 8) { dvbcsa_bs_word_t t, b; for (i = 0; i < 4; i++) { t = row[j + i]; b = row[j + 4 + i]; row[j + i] = BS_OR(BS_AND(t, BS_VAL8(0f)), BS_SHL(BS_AND(b, BS_VAL8(0f)), 4)); row[j + 4 + i] = BS_OR(BS_AND(b, BS_VAL8(f0)), BS_SHR(BS_AND(t, BS_VAL8(f0)), 4)); } } for (j = 0; j < 64; j += 4) { dvbcsa_bs_word_t t, b; for (i = 0; i < 2; i++) { t = row[j + i]; b = row[j + 2 + i]; row[j + i] = BS_OR(BS_AND(t, BS_VAL8(33)), BS_SHL(BS_AND(b, BS_VAL8(33)), 2)); row[j + 2 + i] = BS_OR(BS_AND(b, BS_VAL8(cc)), BS_SHR(BS_AND(t, BS_VAL8(cc)), 2)); } } for (j = 0; j < 64; j += 2) { dvbcsa_bs_word_t t, b; t = row[j]; b = row[j + 1]; row[j] = BS_OR(BS_AND(t, BS_VAL8(55)), BS_SHL(BS_AND(b, BS_VAL8(55)), 1)); row[j + 1] = BS_OR(BS_AND(b, BS_VAL8(aa)), BS_SHR(BS_AND(t, BS_VAL8(aa)), 1)); } }
void aycw_bit2byteslice(dvbcsa_bs_word_t *data, int count) { int i, j, k; dvbcsa_bs_word_t *p = data; dvbcsa_bs_word_t *row = data; for (k = 0; k < 8 * count; k++) { for (i = 0; i < 4; i++) { dvbcsa_bs_word_t t, b; t = p[i]; b = p[4 + i]; p[i + 0] = BS_OR(BS_AND(t, BS_VAL32(0000ffff)), BS_SHL8(BS_AND(b, BS_VAL32(0000ffff)), 2)); p[i + 4] = BS_OR(BS_AND(b, BS_VAL32(ffff0000)), BS_SHR8(BS_AND(t, BS_VAL32(ffff0000)), 2)); } for (j = 0; j < 8; j += 4) { dvbcsa_bs_word_t t, b; for (i = 0; i < 2; i++) { t = p[j + i]; b = p[j + 2 + i]; p[j + i + 0] = BS_OR(BS_AND(t, BS_VAL16(00ff)), BS_SHL8(BS_AND(b, BS_VAL16(00ff)), 1)); p[j + i + 2] = BS_OR(BS_AND(b, BS_VAL16(ff00)), BS_SHR8(BS_AND(t, BS_VAL16(ff00)), 1)); } } for (j = 0; j < 8; j += 2) { dvbcsa_bs_word_t t, b; t = p[j]; b = p[j + 1]; p[j + 0] = BS_OR(BS_AND(t, BS_VAL8(0f)), BS_SHL(BS_AND(b, BS_VAL8(0f)), 4)); //(t & 0x0f0f0f0f) | ((b & 0x0f0f0f0f) << 4); p[j + 1] = BS_OR(BS_AND(b, BS_VAL8(f0)), BS_SHR(BS_AND(t, BS_VAL8(f0)), 4));//((t & 0xf0f0f0f0) >> 4) | (b & 0xf0f0f0f0); } for (j = 0; j < 8; j++) { dvbcsa_bs_word_t t; t = p[j]; t = BS_OR( BS_AND(t, BS_VAL32(cccc3333)), BS_OR( BS_SHR(BS_AND(t, BS_VAL32(33330000)), 14), BS_SHL(BS_AND(t, BS_VAL32(0000cccc)), 14) ) ); t = BS_OR( BS_AND(t, BS_VAL16(aa55)), BS_OR( BS_SHR(BS_AND(t, BS_VAL16(5500)), 7), BS_SHL(BS_AND(t, BS_VAL16(00aa)), 7) ) ); t = BS_OR(BS_AND(t, BS_VAL8(81)), BS_OR(BS_SHR(BS_AND(t, BS_VAL8(10)), 3), BS_OR(BS_SHR(BS_AND(t, BS_VAL8(20)), 2), BS_OR(BS_SHR(BS_AND(t, BS_VAL8(40)), 1), BS_OR(BS_SHL(BS_AND(t, BS_VAL8(02)), 1), BS_OR(BS_SHL(BS_AND(t, BS_VAL8(04)), 2), BS_SHL(BS_AND(t, BS_VAL8(08)), 3))))))); p[j] = t; } /* for (j = 0; j < 8; j++) */ /* OPTIMIZEME: following loops are only for re ordering bytes. Can be included in expressions above? */ for (i = 0; i < 4; i++) { dvbcsa_bs_word_t t, b; t = p[i]; b = p[4 + i]; p[i + 0] = BS_OR(BS_AND(t, BS_VAL(0x00000000, 0x00000000, 0xffffffff, 0xffffffff)), BS_SHL8(BS_AND(b, BS_VAL(0x00000000, 0x00000000, 0xffffffff, 0xffffffff)), 8)); p[i + 4] = BS_OR(BS_AND(b, BS_VAL(0xffffffff, 0xffffffff, 0x00000000, 0x00000000)), BS_SHR8(BS_AND(t, BS_VAL(0xffffffff, 0xffffffff, 0x00000000, 0x00000000)), 8)); } for (j = 0; j < 8; j += 4) { for (i = 0; i < 2; i++) { dvbcsa_bs_word_t t, b; t = p[j + i]; b = p[j + 2 + i]; p[j + i + 0] = BS_OR(BS_AND(t, BS_VAL(0x00000000, 0x00000000, 0xffffffff, 0xffffffff)), BS_SHL8(BS_AND(b, BS_VAL(0x00000000, 0x00000000, 0xffffffff, 0xffffffff)), 8)); p[j + i + 2] = BS_OR(BS_AND(b, BS_VAL(0xffffffff, 0xffffffff, 0x00000000, 0x00000000)), BS_SHR8(BS_AND(t, BS_VAL(0xffffffff, 0xffffffff, 0x00000000, 0x00000000)), 8)); t = p[j + i]; b = p[j + 2 + i]; p[j + i + 0] = BS_OR(BS_AND(t, BS_VAL(0x00000000, 0xffffffff, 0x00000000, 0xffffffff)), BS_SHL8(BS_AND(b, BS_VAL(0x00000000, 0xffffffff, 0x00000000, 0xffffffff)), 4)); p[j + i + 2] = BS_OR(BS_AND(b, BS_VAL(0xffffffff, 0x00000000, 0xffffffff, 0x00000000)), BS_SHR8(BS_AND(t, BS_VAL(0xffffffff, 0x00000000, 0xffffffff, 0x00000000)), 4)); } } for (j = 0; j < 8; j += 2) { dvbcsa_bs_word_t t, b; t = p[j]; b = p[j + 1]; p[j + 0] = BS_OR(BS_AND(t, BS_VAL(0x00000000, 0xffffffff, 0x00000000, 0xffffffff)), BS_SHL8(BS_AND(b, BS_VAL(0x00000000, 0xffffffff, 0x00000000, 0xffffffff)), 4)); p[j + 1] = BS_OR(BS_AND(b, BS_VAL(0xffffffff, 0x00000000, 0xffffffff, 0x00000000)), BS_SHR8(BS_AND(t, BS_VAL(0xffffffff, 0x00000000, 0xffffffff, 0x00000000)), 4)); } p += 8; row=p; } /* for (k=0; k<8 ; k++) */ }
void dvbcsa_bs_stream_transpose_in(const struct dvbcsa_bs_batch_s *pcks, dvbcsa_bs_word_t *row) { int i, j; for (i = 0; pcks[i].data; i++) if (pcks[i].len >= 8) row[i] = BS_VAL(dvbcsa_load_le64(pcks[i].data)); for (i = 0; i < 32; i++) { dvbcsa_bs_word_t t, b; t = row[i]; b = row[32 + i]; row[i] = BS_OR(BS_AND(t, BS_VAL64(00000000ffffffff)), BS_SHL8(b, 4)); row[32 + i] = BS_OR(BS_AND(b, BS_VAL64(ffffffff00000000)), BS_SHR8(t, 4)); } for (j = 0; j < 64; j += 32) { dvbcsa_bs_word_t t, b; for (i = 0; i < 16; i++) { t = row[j + i]; b = row[j + 16 + i]; row[j + i] = BS_OR(BS_AND(t, BS_VAL32(0000ffff)), BS_SHL8(BS_AND(b, BS_VAL32(0000ffff)), 2)); row[j + 16 + i] = BS_OR(BS_AND(b, BS_VAL32(ffff0000)), BS_SHR8(BS_AND(t, BS_VAL32(ffff0000)), 2)); } } for (j = 0; j < 64; j += 16) { dvbcsa_bs_word_t t, b; for (i = 0; i < 8; i++) { t = row[j + i]; b = row[j + 8 + i]; row[j + i] = BS_OR(BS_AND(t, BS_VAL16(00ff)), BS_SHL8(BS_AND(b, BS_VAL16(00ff)), 1)); row[j + 8 + i] = BS_OR(BS_AND(b, BS_VAL16(ff00)), BS_SHR8(BS_AND(t, BS_VAL16(ff00)), 1)); } } for (j = 0; j < 64; j += 8) { dvbcsa_bs_word_t t, b; for (i = 0; i < 4; i++) { b = row[j + i]; t = row[j + 4 + i]; row[j + i] = BS_OR(BS_AND(b, BS_VAL8(0f)), BS_SHL(BS_AND(t, BS_VAL8(0f)), 4)); row[j + 4 + i] = BS_OR(BS_AND(t, BS_VAL8(f0)), BS_SHR(BS_AND(b, BS_VAL8(f0)), 4)); } } for (j = 0; j < 64; j += 4) { dvbcsa_bs_word_t t, b; for (i = 0; i < 2; i++) { b = row[j + i]; t = row[j + 2 + i]; row[j + i] = BS_OR(BS_AND(b, BS_VAL8(33)), BS_SHL(BS_AND(t, BS_VAL8(33)), 2)); row[j + 2 + i] = BS_OR(BS_AND(t, BS_VAL8(cc)), BS_SHR(BS_AND(b, BS_VAL8(cc)), 2)); } } for (j = 0; j < 64; j += 2) { dvbcsa_bs_word_t t, b; b = row[j]; t = row[j + 1]; row[j] = BS_OR(BS_AND(b, BS_VAL8(55)), BS_SHL(BS_AND(t, BS_VAL8(55)), 1)); row[j + 1] = BS_OR(BS_AND(t, BS_VAL8(aa)), BS_SHR(BS_AND(b, BS_VAL8(aa)), 1)); } }
void dvbcsa_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++) { A[i][b] = key->stream[b + i * 4]; B[i][b] = key->stream[b + i * 4 + 32]; } // 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); } }
AYCW_INLINE void aycw__vInitVariables(aycw_tstPQXYZ * stPQXYZ, aycw_tstCDEF *stCDEF , dvbcsa_bs_word_t * BS_Streambit0, dvbcsa_bs_word_t * BS_Streambit1) { uint8 i; /* init values */ for (i = 0; i < 4; i++) { stPQXYZ->BS_X[i] = BS_VAL8(00); stPQXYZ->BS_Y[i] = BS_VAL8(00); stPQXYZ->BS_Z[i] = BS_VAL8(00); stCDEF->BS_D[i] = BS_VAL8(00); stCDEF->BS_E[i] = BS_VAL8(00); stCDEF->BS_F[i] = BS_VAL8(00); } stPQXYZ->BS_P = BS_VAL8(00); stPQXYZ->BS_Q = BS_VAL8(00); stCDEF->BS_C = BS_VAL8(00); *BS_Streambit0 = BS_VAL8(00); *BS_Streambit1 = BS_VAL8(00); }