aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFraxinas <andreas.frisch@multimedia-labs.de>2010-04-14 14:09:09 +0200
committerFraxinas <andreas.frisch@multimedia-labs.de>2010-04-14 14:09:09 +0200
commit5744198c4276074cb812e23760f41e647dc0edd7 (patch)
tree8fce725d9b9ab7dfde667064d73dc93ac71fce63 /lib
parent98c7a787df63a93f868548c2b1e357c0d873ebbe (diff)
parent1401e6b972efb009c2a7602e41abe6c1c809a63e (diff)
downloadenigma2-5744198c4276074cb812e23760f41e647dc0edd7.tar.gz
enigma2-5744198c4276074cb812e23760f41e647dc0edd7.zip
Merge branch 'experimental' of git.opendreambox.org:/git/enigma2 into experimental
Diffstat (limited to 'lib')
-rw-r--r--lib/base/Makefile.am2
-rw-r--r--lib/base/etpm.cpp172
-rw-r--r--lib/base/etpm.h44
-rw-r--r--lib/gui/elistboxcontent.cpp5
-rwxr-xr-xlib/python/Plugins/DemoPlugins/Makefile.am6
-rw-r--r--lib/python/Plugins/DemoPlugins/TPMDemo/Makefile.am5
-rw-r--r--lib/python/Plugins/DemoPlugins/TPMDemo/README1
-rw-r--r--lib/python/Plugins/DemoPlugins/TPMDemo/__init__.py0
-rw-r--r--lib/python/Plugins/DemoPlugins/TPMDemo/plugin.py87
-rw-r--r--lib/python/Plugins/Makefile.am1
-rw-r--r--lib/python/enigma_python.i2
11 files changed, 320 insertions, 5 deletions
diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am
index 6ea9d03f..05085632 100644
--- a/lib/base/Makefile.am
+++ b/lib/base/Makefile.am
@@ -8,5 +8,5 @@ libenigma_base_a_SOURCES = \
init.cpp message.cpp thread.cpp \
smartptr.cpp estring.cpp connection.cpp \
filepush.cpp encoding.cpp console.cpp rawfile.cpp \
- nconfig.cpp ioprio.cpp
+ nconfig.cpp ioprio.cpp etpm.cpp
diff --git a/lib/base/etpm.cpp b/lib/base/etpm.cpp
new file mode 100644
index 00000000..9a443e0a
--- /dev/null
+++ b/lib/base/etpm.cpp
@@ -0,0 +1,172 @@
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+#include <lib/base/eerror.h>
+
+#include "etpm.h"
+
+eTPM::eTPM()
+{
+ struct sockaddr_un addr;
+ unsigned char buf[8];
+ unsigned int tag;
+ size_t len;
+ unsigned char *val;
+
+ level2_cert_read = level3_cert_read = false;
+
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, TPMD_SOCKET);
+
+ fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0)
+ {
+ eDebug("[eTPM] socket error");
+ return;
+ }
+
+ if (connect(fd, (const struct sockaddr *)&addr, SUN_LEN(&addr)) < 0)
+ {
+ eDebug("[eTPM] connect error");
+ return;
+ }
+
+ buf[0] = TPMD_DT_LEVEL2_CERT;
+ buf[1] = TPMD_DT_LEVEL3_CERT;
+ if (!send_cmd(TPMD_CMD_GET_DATA, buf, 2))
+ {
+ return;
+ }
+
+ val = (unsigned char*)recv_cmd(&tag, &len);
+ if (val == NULL)
+ {
+ return;
+ }
+
+ parse_data(val, len);
+ free(val);
+}
+
+eTPM::~eTPM()
+{
+
+}
+
+bool eTPM::send_cmd(enum tpmd_cmd cmd, const void *data, size_t len)
+{
+ unsigned char buf[len + 4];
+
+ buf[0] = (cmd >> 8) & 0xff;
+ buf[1] = (cmd >> 0) & 0xff;
+ buf[2] = (len >> 8) & 0xff;
+ buf[3] = (len >> 0) & 0xff;
+ memcpy(&buf[4], data, len);
+
+ if (write(fd, buf, sizeof(buf)) != (ssize_t)sizeof(buf))
+ {
+ fprintf(stderr, "%s: incomplete write\n", __func__);
+ return false;
+ }
+
+ return true;
+}
+
+void* eTPM::recv_cmd(unsigned int *tag, size_t *len)
+{
+ unsigned char buf[4];
+ void *val;
+
+ if (read(fd, buf, 4) != 4)
+ {
+ fprintf(stderr, "%s: incomplete read\n", __func__);
+ return NULL;
+ }
+
+ *tag = (buf[0] << 8) | buf[1];
+ *len = (buf[2] << 8) | buf[3];
+
+ val = malloc(*len);
+ if (val == NULL)
+ return NULL;
+
+ ssize_t rd = read(fd, val, *len);
+ if (rd < 0)
+ {
+ perror("eTPM::recv_cmd read");
+ free(val);
+ }
+ else if ((size_t)rd != *len) {
+ fprintf(stderr, "%s: incomplete read\n", __func__);
+ free(val);
+ return NULL;
+ }
+
+ return val;
+}
+
+void eTPM::parse_data(const unsigned char *data, size_t datalen)
+{
+ unsigned int i;
+ unsigned int tag;
+ unsigned int len;
+ const unsigned char *val;
+
+ for (i = 0; i < datalen; i += len) {
+ tag = data[i++];
+ len = data[i++];
+ val = &data[i];
+
+ switch (tag) {
+ case TPMD_DT_LEVEL2_CERT:
+ if (len != 210)
+ break;
+ memcpy(level2_cert, val, 210);
+ level2_cert_read = true;
+ break;
+ case TPMD_DT_LEVEL3_CERT:
+ if (len != 210)
+ break;
+ memcpy(level3_cert, val, 210);
+ level3_cert_read = true;
+ break;
+ }
+ }
+}
+
+std::string eTPM::getCert(cert_type type)
+{
+ if (type == TPMD_DT_LEVEL2_CERT && level2_cert_read)
+ return std::string((char*)level2_cert, 210);
+ else if (type == TPMD_DT_LEVEL3_CERT && level3_cert_read)
+ return std::string((char*)level3_cert, 210);
+ return "";
+}
+
+std::string eTPM::challenge(std::string rnd)
+{
+ if (rnd.length() == 8)
+ {
+ if (!send_cmd(TPMD_CMD_COMPUTE_SIGNATURE, rnd.c_str(), 8))
+ return "";
+
+ unsigned int tag;
+ size_t len;
+ unsigned char *val = (unsigned char*)recv_cmd(&tag, &len);
+
+ if (tag != TPMD_CMD_COMPUTE_SIGNATURE)
+ return "";
+
+ std::string ret((char*)val, len);
+ free(val);
+ return ret;
+ }
+ return "";
+}
diff --git a/lib/base/etpm.h b/lib/base/etpm.h
new file mode 100644
index 00000000..c9e52140
--- /dev/null
+++ b/lib/base/etpm.h
@@ -0,0 +1,44 @@
+#ifndef __lib_base_etpm_h
+#define __lib_base_etpm_h
+
+#ifndef SWIG
+#define TPMD_SOCKET "/var/run/tpmd_socket"
+#endif
+
+#include <string>
+
+class eTPM
+{
+#ifndef SWIG
+ int fd;
+ unsigned char level2_cert[210];
+ unsigned char level3_cert[210];
+ bool level2_cert_read;
+ bool level3_cert_read;
+
+ enum tpmd_cmd {
+ TPMD_CMD_RESERVED = 0x0000,
+ TPMD_CMD_GET_DATA = 0x0001,
+ TPMD_CMD_APDU = 0x0002,
+ TPMD_CMD_COMPUTE_SIGNATURE = 0x0003,
+ TPMD_CMD_APP_CERT = 0x0004,
+ };
+
+ bool send_cmd(enum tpmd_cmd cmd, const void *data, size_t len);
+ void *recv_cmd(unsigned int *tag, size_t *len);
+ void parse_data(const unsigned char *data, size_t datalen);
+
+#endif
+public:
+ eTPM();
+ ~eTPM();
+
+ enum cert_type {
+ TPMD_DT_LEVEL2_CERT = 0x04,
+ TPMD_DT_LEVEL3_CERT = 0x05
+ };
+ std::string getCert(cert_type type);
+ std::string challenge(std::string rnd);
+};
+
+#endif // __lib_base_etpm_h
diff --git a/lib/gui/elistboxcontent.cpp b/lib/gui/elistboxcontent.cpp
index 4465d84c..b9e71df8 100644
--- a/lib/gui/elistboxcontent.cpp
+++ b/lib/gui/elistboxcontent.cpp
@@ -49,7 +49,8 @@ int iListboxContent::currentCursorSelectable()
DEFINE_REF(eListboxPythonStringContent);
-eListboxPythonStringContent::eListboxPythonStringContent(): m_itemheight(25), m_cursor(0)
+eListboxPythonStringContent::eListboxPythonStringContent()
+ :m_cursor(0), m_itemheight(25)
{
}
@@ -81,7 +82,7 @@ int eListboxPythonStringContent::cursorMove(int count)
int eListboxPythonStringContent::cursorValid()
{
- return ((unsigned int)m_cursor) < size();
+ return m_cursor < size();
}
int eListboxPythonStringContent::cursorSet(int n)
diff --git a/lib/python/Plugins/DemoPlugins/Makefile.am b/lib/python/Plugins/DemoPlugins/Makefile.am
index aace17cc..9e16bfc1 100755
--- a/lib/python/Plugins/DemoPlugins/Makefile.am
+++ b/lib/python/Plugins/DemoPlugins/Makefile.am
@@ -1,6 +1,8 @@
installdir = $(pkglibdir)/python/Plugins/DemoPlugins
-SUBDIRS = TestPlugin
+SUBDIRS = TestPlugin TPMDemo
install_PYTHON = \
- __init__.py \ No newline at end of file
+ __init__.py
+
+ \ No newline at end of file
diff --git a/lib/python/Plugins/DemoPlugins/TPMDemo/Makefile.am b/lib/python/Plugins/DemoPlugins/TPMDemo/Makefile.am
new file mode 100644
index 00000000..3ccca98e
--- /dev/null
+++ b/lib/python/Plugins/DemoPlugins/TPMDemo/Makefile.am
@@ -0,0 +1,5 @@
+installdir = $(LIBDIR)/enigma2/python/Plugins/DemoPlugins/TPMDemo
+
+install_PYTHON = \
+ __init__.py \
+ plugin.py
diff --git a/lib/python/Plugins/DemoPlugins/TPMDemo/README b/lib/python/Plugins/DemoPlugins/TPMDemo/README
new file mode 100644
index 00000000..89a972aa
--- /dev/null
+++ b/lib/python/Plugins/DemoPlugins/TPMDemo/README
@@ -0,0 +1 @@
+Please read enigma2/doc/TPM for further instructions on how to integrate this into your own plugins. \ No newline at end of file
diff --git a/lib/python/Plugins/DemoPlugins/TPMDemo/__init__.py b/lib/python/Plugins/DemoPlugins/TPMDemo/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/lib/python/Plugins/DemoPlugins/TPMDemo/__init__.py
diff --git a/lib/python/Plugins/DemoPlugins/TPMDemo/plugin.py b/lib/python/Plugins/DemoPlugins/TPMDemo/plugin.py
new file mode 100644
index 00000000..2c078d35
--- /dev/null
+++ b/lib/python/Plugins/DemoPlugins/TPMDemo/plugin.py
@@ -0,0 +1,87 @@
+from Screens.Screen import Screen
+from Plugins.Plugin import PluginDescriptor
+from enigma import eTPM
+import sha
+
+def bin2long(s):
+ return reduce( lambda x,y:(x<<8L)+y, map(ord, s))
+
+def long2bin(l):
+ res = ""
+ for byte in range(128):
+ res += chr((l >> (1024 - (byte + 1) * 8)) & 0xff)
+ return res
+
+def rsa_pub1024(src, mod):
+ return long2bin(pow(bin2long(src), 65537, bin2long(mod)))
+
+def decrypt_block(src, mod):
+ if len(src) != 128 and len(src) != 202:
+ return None
+ dest = rsa_pub1024(src[:128], mod)
+ hash = sha.new(dest[1:107])
+ if len(src) == 202:
+ hash.update(src[131:192])
+ result = hash.digest()
+ if result == dest[107:127]:
+ return dest
+ return None
+
+def validate_cert(cert, key):
+ buf = decrypt_block(cert[8:], key)
+ if buf is None:
+ return None
+ return buf[36:107] + cert[139:196]
+
+def read_random():
+ try:
+ fd = open("/dev/urandom", "r")
+ buf = fd.read(8)
+ fd.close()
+ return buf
+ except:
+ return None
+
+def main(session, **kwargs):
+ try:
+ device = open("/proc/stb/info/model", "r").readline().strip()
+ except:
+ device = ""
+ if device != "dm7025":
+ rootkey = ['\x9f', '|', '\xe4', 'G', '\xc9', '\xb4', '\xf4', '#', '&', '\xce', '\xb3', '\xfe', '\xda', '\xc9', 'U', '`', '\xd8', '\x8c', 's', 'o', '\x90', '\x9b', '\\', 'b', '\xc0', '\x89', '\xd1', '\x8c', '\x9e', 'J', 'T', '\xc5', 'X', '\xa1', '\xb8', '\x13', '5', 'E', '\x02', '\xc9', '\xb2', '\xe6', 't', '\x89', '\xde', '\xcd', '\x9d', '\x11', '\xdd', '\xc7', '\xf4', '\xe4', '\xe4', '\xbc', '\xdb', '\x9c', '\xea', '}', '\xad', '\xda', 't', 'r', '\x9b', '\xdc', '\xbc', '\x18', '3', '\xe7', '\xaf', '|', '\xae', '\x0c', '\xe3', '\xb5', '\x84', '\x8d', '\r', '\x8d', '\x9d', '2', '\xd0', '\xce', '\xd5', 'q', '\t', '\x84', 'c', '\xa8', ')', '\x99', '\xdc', '<', '"', 'x', '\xe8', '\x87', '\x8f', '\x02', ';', 'S', 'm', '\xd5', '\xf0', '\xa3', '_', '\xb7', 'T', '\t', '\xde', '\xa7', '\xf1', '\xc9', '\xae', '\x8a', '\xd7', '\xd2', '\xcf', '\xb2', '.', '\x13', '\xfb', '\xac', 'j', '\xdf', '\xb1', '\x1d', ':', '?']
+
+ etpm = eTPM()
+ l2cert = etpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT)
+ if l2cert is None:
+ print "l2cert not found"
+ return
+
+ l2key = validate_cert(l2cert, rootkey)
+ if l2key is None:
+ print "l2cert invalid"
+ return
+
+ l3cert = etpm.getCert(eTPM.TPMD_DT_LEVEL3_CERT)
+ if l3cert is None:
+ print "l3cert not found (can be fixed by running the genuine dreambox plugin and running the offered update)"
+ return
+
+ l3key = validate_cert(l3cert, l2key)
+ if l3key is None:
+ print "l3cert invalid"
+ return
+
+ rnd = read_random()
+ if rnd is None:
+ print "random error"
+ return
+ val = etpm.challenge(rnd)
+ result = decrypt_block(val, l3key)
+ if device == "dm7025" or result[80:88] == rnd:
+ print "successfully finished the tpm test"
+ # would start your plugin here
+
+def Plugins(**kwargs):
+ return [PluginDescriptor(name = "TPM Demo", description = _("A demo plugin for TPM usage."), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc = main),
+ PluginDescriptor(name = "TPM Demo", description = _("A demo plugin for TPM usage."), icon = "plugin.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc = main)]
+ \ No newline at end of file
diff --git a/lib/python/Plugins/Makefile.am b/lib/python/Plugins/Makefile.am
index f0435036..79d2b0b6 100644
--- a/lib/python/Plugins/Makefile.am
+++ b/lib/python/Plugins/Makefile.am
@@ -4,3 +4,4 @@ SUBDIRS = Extensions SystemPlugins DemoPlugins
install_PYTHON = \
__init__.py Plugin.py
+
diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i
index 2fec2ff1..19fb9254 100644
--- a/lib/python/enigma_python.i
+++ b/lib/python/enigma_python.i
@@ -39,6 +39,7 @@ is usually caused by not marking PSignals as immutable.
#include <lib/base/ebase.h>
#include <lib/base/smartptr.h>
#include <lib/base/eerror.h>
+#include <lib/base/etpm.h>
#include <lib/base/nconfig.h>
#include <lib/base/message.h>
#include <lib/driver/rc.h>
@@ -157,6 +158,7 @@ typedef long time_t;
%immutable ePythonMessagePump::recv_msg;
%immutable eDVBLocalTimeHandler::m_timeUpdated;
%include <lib/base/message.h>
+%include <lib/base/etpm.h>
%include <lib/base/nconfig.h>
%include <lib/driver/rc.h>
%include <lib/gdi/fb.h>