${BUILDDIR}/src/descrambler/ffdecsa/ffdecsa_sse2.o : CFLAGS += -msse2
endif
-# libaesdec
+# crypto algorithms
SRCS-${CONFIG_SSL} += src/descrambler/algo/libaesdec.c
+SRCS-${CONFIG_SSL} += src/descrambler/algo/libdesdec.c
# DBUS
SRCS-${CONFIG_DBUS_1} += src/dbus.c
}
/* allocate key structure */
-void * aes_get_key_struct(void)
+void * aes_get_priv_struct(void)
{
aes_priv_t *keys;
}
/* free key structure */
-void aes_free_key_struct(void *keys)
+void aes_free_priv_struct(void *keys)
{
free(keys);
}
/* decrypt */
-void aes_decrypt_packet(void *keys, uint8_t *pkt)
+void aes_decrypt_packet(void *keys, const uint8_t *pkt)
{
uint8_t ev_od = 0;
uint_fast8_t xc0, offset, n;
if (xc0 == 0x80 || xc0 == 0xc0) { // encrypted
ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd
- pkt[3] &= 0x3f; // consider it decrypted now
+ ((uint8_t *)pkt)[3] &= 0x3f; // consider it decrypted now
if (pkt[3] & 0x20) { // incomplete packet
offset = 4 + pkt[4] + 1;
n = (188 - offset) >> 4;
k = &((aes_priv_t *) keys)->keys[ev_od];
for (; offset <= (188 - 16); offset += 16) {
- AES_ecb_encrypt(pkt + offset, pkt + offset, k, AES_DECRYPT);
+ AES_ecb_encrypt(pkt + offset, (uint8_t *)(pkt + offset), k, AES_DECRYPT);
}
}
#if ENABLE_SSL
-void *aes_get_key_struct(void);
-void aes_free_key_struct(void *keys);
+void *aes_get_priv_struct(void);
+void aes_free_priv_struct(void *keys);
void aes_set_control_words(void *keys, const uint8_t *even, const uint8_t *odd);
void aes_set_even_control_word(void *keys, const uint8_t *even);
void aes_set_odd_control_word(void *keys, const uint8_t *odd);
-void aes_decrypt_packet(void *keys, uint8_t *pkt);
+void aes_decrypt_packet(void *keys, const uint8_t *pkt);
#else
// empty functions
-static inline void *aes_get_key_struct(void) { return 0; };
-static inline void aes_free_key_struct(void *keys) { return; };
+static inline void *aes_get_priv_struct(void) { return NULL; };
+static inline void aes_free_priv_struct(void *keys) { return; };
static inline void aes_set_control_words(void *keys, const uint8_t *even, const uint8_t *odd) { return; };
static inline void aes_set_even_control_word(void *keys, const uint8_t *even) { return; };
static inline void aes_set_odd_control_word(void *keys, const uint8_t *odd) { return; };
-static inline void aes_decrypt_packet(void *keys, uint8_t *pkt) { return; };
+static inline void aes_decrypt_packet(void *keys, const uint8_t *pkt) { return; };
#endif
--- /dev/null
+/*
+ * libaesdec.c
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "openssl/des.h"
+
+#include "libdesdec.h"
+
+/* key structure */
+typedef struct des_priv {
+ DES_key_schedule sched[2]; /* 0 = even, 1 = odd */
+} des_priv_t;
+
+/* even cw represents one 64-bit DES key */
+void des_set_even_control_word(void *priv, const uint8_t *pk)
+{
+ DES_set_key_unchecked((const_DES_cblock *)pk, &((des_priv_t *)priv)->sched[0]);
+}
+
+/* odd cw represents one 64-bit DES key */
+void des_set_odd_control_word(void *priv, const uint8_t *pk)
+{
+ DES_set_key_unchecked((const_DES_cblock *)pk, &((des_priv_t *)priv)->sched[1]);
+}
+
+/* set control words */
+void des_set_control_words(void *priv,
+ const uint8_t *ev,
+ const uint8_t *od)
+{
+ DES_set_key_unchecked((const_DES_cblock *)ev, &((des_priv_t *)priv)->sched[0]);
+ DES_set_key_unchecked((const_DES_cblock *)od, &((des_priv_t *)priv)->sched[1]);
+}
+
+/* allocate key structure */
+void * des_get_priv_struct(void)
+{
+ des_priv_t *priv;
+
+ priv = (des_priv_t *) malloc(sizeof(des_priv_t));
+ if (priv) {
+ static const uint8_t pk[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ des_set_control_words(priv, pk, pk);
+ }
+ return priv;
+}
+
+/* free key structure */
+void des_free_priv_struct(void *priv)
+{
+ free(priv);
+}
+
+/* decrypt */
+void des_decrypt_packet(void *priv, const uint8_t *pkt)
+{
+ uint8_t ev_od = 0;
+ uint_fast8_t xc0, offset, offset2, n;
+ DES_key_schedule *sched;
+ uint8_t buf[188];
+
+ xc0 = pkt[3] & 0xc0;
+
+ //skip clear pkt
+ if (xc0 == 0x00)
+ return;
+
+ //skip reserved pkt
+ if (xc0 == 0x40)
+ return;
+
+ if (xc0 == 0x80 || xc0 == 0xc0) { // encrypted
+ ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd
+ ((uint8_t *)pkt)[3] &= 0x3f; // consider it decrypted now
+ if (pkt[3] & 0x20) { // incomplete packet
+ offset = 4 + pkt[4] + 1;
+ n = (188 - offset) >> 4;
+ if (n == 0) { // decrypted==encrypted!
+ return; // this doesn't need more processing
+ }
+ } else {
+ offset = 4;
+ }
+ } else {
+ return;
+ }
+
+ sched = &((des_priv_t *)priv)->sched[ev_od];
+ if (offset & 3) {
+ /* data must be aligned for DES_encrypt2() */
+ offset2 = (offset + 3) & ~3;
+ memcpy(buf + offset2, pkt + offset, 188 - offset2);
+ for (; offset2 <= (188 - 8); offset2 += 8) {
+ DES_encrypt2((DES_LONG *)(buf + offset2), sched, 0);
+ }
+ memcpy((uint8_t *)(pkt + offset), buf + offset2, 188 - offset2);
+ } else {
+ for (; offset <= (188 - 8); offset += 8) {
+ DES_encrypt2((DES_LONG *)(pkt + offset), sched, 0);
+ }
+ }
+}
--- /dev/null
+/*
+ * libdesdec.h
+ */
+
+#ifndef LIBDESDEC_H_
+#define LIBDESDEC_H_
+
+#include <stdint.h>
+#include "build.h"
+
+#if ENABLE_SSL
+
+void *des_get_priv_struct(void);
+void des_free_priv_struct(void *priv);
+void des_set_control_words(void *priv, const uint8_t *even, const uint8_t *odd);
+void des_set_even_control_word(void *priv, const uint8_t *even);
+void des_set_odd_control_word(void *priv, const uint8_t *odd);
+void des_decrypt_packet(void *priv, const uint8_t *pkt);
+
+#else
+
+// empty functions
+static inline void *des_get_priv_struct(void) { return NULL; };
+static inline void des_free_priv_struct(void *priv) { return; };
+static inline void des_set_control_words(void *priv, const uint8_t *even, const uint8_t *odd) { return; };
+static inline void des_set_even_control_word(void *priv, const uint8_t *even) { return; };
+static inline void des_set_odd_control_word(void *priv, const uint8_t *odd) { return; };
+static inline void des_decrypt_packet(void *priv, const uint8_t *pkt) { return; };
+
+#endif
+
+#endif /* LIBDESDEC_H_ */
#include <assert.h>
static void
-tvhcsa_aes_flush
+tvhcsa_aes_ecb_flush
( tvhcsa_t *csa, struct mpegts_service *s )
{
/* empty - no queue */
}
static void
-tvhcsa_aes_descramble
+tvhcsa_aes_ecb_descramble
( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb, int len )
{
const uint8_t *tsb2, *end2;
for (tsb2 = tsb, end2 = tsb + len; tsb2 < end2; tsb2 += 188)
- aes_decrypt_packet(csa->csa_aes_keys, (unsigned char *)tsb2);
+ aes_decrypt_packet(csa->csa_aes_priv, tsb2);
+ ts_recv_packet2(s, tsb, len);
+}
+
+static void
+tvhcsa_des_ncb_flush
+ ( tvhcsa_t *csa, struct mpegts_service *s )
+{
+ /* empty - no queue */
+}
+
+static void
+tvhcsa_des_ncb_descramble
+ ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb, int len )
+{
+ const uint8_t *tsb2, *end2;
+
+ for (tsb2 = tsb, end2 = tsb + len; tsb2 < end2; tsb2 += 188)
+ des_decrypt_packet(csa->csa_des_priv, tsb2);
ts_recv_packet2(s, tsb, len);
}
csa->csa_flush = tvhcsa_csa_cbc_flush;
csa->csa_keylen = 8;
break;
+ case DESCRAMBLER_DES_NCB:
+ csa->csa_descramble = tvhcsa_des_ncb_descramble;
+ csa->csa_flush = tvhcsa_des_ncb_flush;
+ csa->csa_keylen = 8;
+ break;
case DESCRAMBLER_AES_ECB:
- csa->csa_descramble = tvhcsa_aes_descramble;
- csa->csa_flush = tvhcsa_aes_flush;
+ csa->csa_descramble = tvhcsa_aes_ecb_descramble;
+ csa->csa_flush = tvhcsa_aes_ecb_flush;
csa->csa_keylen = 16;
break;
default:
set_even_control_word((csa)->csa_keys, even);
#endif
break;
+ case DESCRAMBLER_DES_NCB:
+ des_set_even_control_word(csa->csa_des_priv, even);
+ break;
case DESCRAMBLER_AES_ECB:
- aes_set_even_control_word(csa->csa_aes_keys, even);
+ aes_set_even_control_word(csa->csa_aes_priv, even);
break;
default:
assert(0);
set_odd_control_word((csa)->csa_keys, odd);
#endif
break;
+ case DESCRAMBLER_DES_NCB:
+ des_set_odd_control_word(csa->csa_des_priv, odd);
+ break;
case DESCRAMBLER_AES_ECB:
- aes_set_odd_control_word(csa->csa_aes_keys, odd);
+ aes_set_odd_control_word(csa->csa_aes_priv, odd);
break;
default:
assert(0);
#else
csa->csa_keys = get_key_struct();
#endif
- csa->csa_aes_keys = aes_get_key_struct();
+ csa->csa_aes_priv = aes_get_priv_struct();
+ csa->csa_des_priv = des_get_priv_struct();
}
void
#else
free_key_struct(csa->csa_keys);
#endif
- aes_free_key_struct(csa->csa_aes_keys);
+ aes_free_priv_struct(csa->csa_aes_priv);
+ des_free_priv_struct(csa->csa_des_priv);
free(csa->csa_tsbcluster);
}
#endif
#include "algo/libaesdec.h"
+#include "algo/libdesdec.h"
typedef struct tvhcsa
{
#else
void *csa_keys;
#endif
- void *csa_aes_keys;
+ void *csa_aes_priv;
+ void *csa_des_priv;
} tvhcsa_t;