/* 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 */ #include "dvbcsa/dvbcsa.h" #include "dvbcsa_bs.h" /*********************************************************************** Block cipher transpose */ void dvbcsa_bs_block_transpose_in (dvbcsa_bs_word_t *out, const struct dvbcsa_bs_batch_s *pcks, unsigned int offset) { uint32_t *ri = (uint32_t *) out; unsigned int j, i, k; for (i = 0; pcks[i].data; i++) if (offset < (pcks[i].len & (unsigned)~0x7)) { ri[i ] = dvbcsa_load_le32(pcks[i].data + offset); ri[i + BS_BATCH_SIZE] = dvbcsa_load_le32(pcks[i].data + offset + 4); } for (j = 0; j < 64; j += 32) for (i = 0; i < 16; i += 8) for (k = 0; k < 8; k++) { dvbcsa_bs_word_t *r = out + j + i + k; dvbcsa_bs_word_t t, b; t = r[0]; b = r[16]; r[0] = BS_OR(BS_AND(t, BS_VAL32(0000ffff)), BS_SHL8(BS_AND(b, BS_VAL32(0000ffff)), 2)); r[16] = BS_OR(BS_AND(b, BS_VAL32(ffff0000)), BS_SHR8(BS_AND(t, BS_VAL32(ffff0000)), 2)); } for (j = 0; j < 64; j += 16) for (k = 0; k < 8; k++) { dvbcsa_bs_word_t *r = out + j + k; dvbcsa_bs_word_t t, b; t = r[0]; b = r[8]; r[0] = BS_OR(BS_AND(t, BS_VAL16(00ff)), BS_SHL8(BS_AND(b, BS_VAL16(00ff)), 1)); r[8] = BS_OR(BS_AND(b, BS_VAL16(ff00)), BS_SHR8(BS_AND(t, BS_VAL16(ff00)), 1)); } } void dvbcsa_bs_block_transpose_out (dvbcsa_bs_word_t *in, const struct dvbcsa_bs_batch_s *pcks, unsigned int offset) { uint32_t *ri = (uint32_t *) in; unsigned int j, i, k; for (j = 0; j < 64; j += 16) for (k = 0; k < 8; k++) { dvbcsa_bs_word_t *r = in + j + k; dvbcsa_bs_word_t t, b; t = r[0]; b = r[8]; r[0] = BS_OR(BS_AND(t, BS_VAL16(00ff)), BS_SHL8(BS_AND(b, BS_VAL16(00ff)), 1)); r[8] = BS_OR(BS_AND(b, BS_VAL16(ff00)), BS_SHR8(BS_AND(t, BS_VAL16(ff00)), 1)); } for (j = 0; j < 64; j += 32) for (i = 0; i < 16; i += 8) for (k = 0; k < 8; k++) { dvbcsa_bs_word_t *r = in + j + i + k; dvbcsa_bs_word_t t, b; t = r[0]; b = r[16]; r[0] = BS_OR(BS_AND(t, BS_VAL32(0000ffff)), BS_SHL8(BS_AND(b, BS_VAL32(0000ffff)), 2)); r[16] = BS_OR(BS_AND(b, BS_VAL32(ffff0000)), BS_SHR8(BS_AND(t, BS_VAL32(ffff0000)), 2)); } for (i = 0; pcks[i].data; i++) if (offset < (pcks[i].len & (unsigned)~0x7)) { dvbcsa_store_le32(pcks[i].data + offset , ri[i ]); dvbcsa_store_le32(pcks[i].data + offset + 4, ri[i + BS_BATCH_SIZE]); } }