From 4007630dac238cccbfddd2ededa484f8fb14eb7c Mon Sep 17 00:00:00 2001 From: Stefan Pluecken Date: Fri, 9 Apr 2010 15:21:13 +0200 Subject: fixes bug #467 add tpm interface to enigma 2 introduce a demo plugin for tpm usage in plugins to validate running on dream multimedia hardware to be used in plugins (see doc/TPM for further information) --- lib/base/etpm.cpp | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 lib/base/etpm.cpp (limited to 'lib/base/etpm.cpp') diff --git a/lib/base/etpm.cpp b/lib/base/etpm.cpp new file mode 100644 index 00000000..f1ac07ba --- /dev/null +++ b/lib/base/etpm.cpp @@ -0,0 +1,161 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DEFINE_REF(eTPM); + +eTPM::eTPM() +{ + struct sockaddr_un addr; + unsigned char buf[8]; + unsigned int tag, 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, unsigned int 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, unsigned int *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; + + if (read(fd, val, *len) != (ssize_t)*len) { + fprintf(stderr, "%s: incomplete read\n", __func__); + free(val); + return NULL; + } + + return val; +} + +void eTPM::parse_data(const unsigned char *data, unsigned int datalen) +{ + unsigned int i, j; + 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; + } + } +} + +PyObject *eTPM::getCert(cert_type type) +{ + if (type == TPMD_DT_LEVEL2_CERT && level2_cert_read) + return PyBuffer_FromMemory(level2_cert, 210); + else if (type == TPMD_DT_LEVEL3_CERT && level3_cert_read) + return PyBuffer_FromMemory(level3_cert, 210); + return Py_None; + +} + +PyObject *eTPM::challenge(PyObject* rnd) +{ + if (PyString_Check(rnd) && PyString_Size(rnd) == 8) + { + char* buf = PyString_AsString(rnd); + if (!send_cmd(TPMD_CMD_COMPUTE_SIGNATURE, buf, 8)) + return Py_None; + + unsigned int tag, len; + unsigned char *val = (unsigned char*)recv_cmd(&tag, &len); + + if (tag != TPMD_CMD_COMPUTE_SIGNATURE) + return Py_None; + + return PyBuffer_FromMemory(val, len); + } + else + return Py_None; +} -- cgit v1.2.3 From 9ef36b8496f187930ff526565546343e503617ab Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 12 Apr 2010 10:59:33 +0200 Subject: lib/base/etpm.cpp: use instead of --- lib/base/etpm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/base/etpm.cpp') diff --git a/lib/base/etpm.cpp b/lib/base/etpm.cpp index f1ac07ba..c2642724 100644 --- a/lib/base/etpm.cpp +++ b/lib/base/etpm.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -103,7 +103,7 @@ void* eTPM::recv_cmd(unsigned int *tag, unsigned int *len) void eTPM::parse_data(const unsigned char *data, unsigned int datalen) { - unsigned int i, j; + unsigned int i; unsigned int tag; unsigned int len; const unsigned char *val; -- cgit v1.2.3 From 1401e6b972efb009c2a7602e41abe6c1c809a63e Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 13 Apr 2010 00:16:15 +0200 Subject: lib/base/etpm.h,cpp: simplify and cleanup code --- lib/base/etpm.cpp | 63 ++++++++++++++++++++++++++++++++----------------------- lib/base/etpm.h | 18 +++++++--------- 2 files changed, 45 insertions(+), 36 deletions(-) (limited to 'lib/base/etpm.cpp') diff --git a/lib/base/etpm.cpp b/lib/base/etpm.cpp index c2642724..9a443e0a 100644 --- a/lib/base/etpm.cpp +++ b/lib/base/etpm.cpp @@ -8,15 +8,16 @@ #include #include #include -#include +#include -DEFINE_REF(eTPM); +#include "etpm.h" eTPM::eTPM() { struct sockaddr_un addr; unsigned char buf[8]; - unsigned int tag, len; + unsigned int tag; + size_t len; unsigned char *val; level2_cert_read = level3_cert_read = false; @@ -25,12 +26,14 @@ eTPM::eTPM() strcpy(addr.sun_path, TPMD_SOCKET); fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (fd < 0) { + if (fd < 0) + { eDebug("[eTPM] socket error"); return; } - if (connect(fd, (const struct sockaddr *)&addr, SUN_LEN(&addr)) < 0) { + if (connect(fd, (const struct sockaddr *)&addr, SUN_LEN(&addr)) < 0) + { eDebug("[eTPM] connect error"); return; } @@ -57,7 +60,7 @@ eTPM::~eTPM() } -bool eTPM::send_cmd(enum tpmd_cmd cmd, const void *data, unsigned int len) +bool eTPM::send_cmd(enum tpmd_cmd cmd, const void *data, size_t len) { unsigned char buf[len + 4]; @@ -67,7 +70,8 @@ bool eTPM::send_cmd(enum tpmd_cmd cmd, const void *data, unsigned int len) buf[3] = (len >> 0) & 0xff; memcpy(&buf[4], data, len); - if (write(fd, buf, sizeof(buf)) != (ssize_t)sizeof(buf)) { + if (write(fd, buf, sizeof(buf)) != (ssize_t)sizeof(buf)) + { fprintf(stderr, "%s: incomplete write\n", __func__); return false; } @@ -75,12 +79,13 @@ bool eTPM::send_cmd(enum tpmd_cmd cmd, const void *data, unsigned int len) return true; } -void* eTPM::recv_cmd(unsigned int *tag, unsigned int *len) +void* eTPM::recv_cmd(unsigned int *tag, size_t *len) { unsigned char buf[4]; void *val; - if (read(fd, buf, 4) != 4) { + if (read(fd, buf, 4) != 4) + { fprintf(stderr, "%s: incomplete read\n", __func__); return NULL; } @@ -92,7 +97,13 @@ void* eTPM::recv_cmd(unsigned int *tag, unsigned int *len) if (val == NULL) return NULL; - if (read(fd, val, *len) != (ssize_t)*len) { + 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; @@ -101,7 +112,7 @@ void* eTPM::recv_cmd(unsigned int *tag, unsigned int *len) return val; } -void eTPM::parse_data(const unsigned char *data, unsigned int datalen) +void eTPM::parse_data(const unsigned char *data, size_t datalen) { unsigned int i; unsigned int tag; @@ -130,32 +141,32 @@ void eTPM::parse_data(const unsigned char *data, unsigned int datalen) } } -PyObject *eTPM::getCert(cert_type type) +std::string eTPM::getCert(cert_type type) { if (type == TPMD_DT_LEVEL2_CERT && level2_cert_read) - return PyBuffer_FromMemory(level2_cert, 210); + return std::string((char*)level2_cert, 210); else if (type == TPMD_DT_LEVEL3_CERT && level3_cert_read) - return PyBuffer_FromMemory(level3_cert, 210); - return Py_None; - + return std::string((char*)level3_cert, 210); + return ""; } -PyObject *eTPM::challenge(PyObject* rnd) +std::string eTPM::challenge(std::string rnd) { - if (PyString_Check(rnd) && PyString_Size(rnd) == 8) + if (rnd.length() == 8) { - char* buf = PyString_AsString(rnd); - if (!send_cmd(TPMD_CMD_COMPUTE_SIGNATURE, buf, 8)) - return Py_None; + if (!send_cmd(TPMD_CMD_COMPUTE_SIGNATURE, rnd.c_str(), 8)) + return ""; - unsigned int tag, len; + unsigned int tag; + size_t len; unsigned char *val = (unsigned char*)recv_cmd(&tag, &len); if (tag != TPMD_CMD_COMPUTE_SIGNATURE) - return Py_None; + return ""; - return PyBuffer_FromMemory(val, len); + std::string ret((char*)val, len); + free(val); + return ret; } - else - return Py_None; + return ""; } diff --git a/lib/base/etpm.h b/lib/base/etpm.h index 3728249b..c9e52140 100644 --- a/lib/base/etpm.h +++ b/lib/base/etpm.h @@ -1,16 +1,14 @@ #ifndef __lib_base_etpm_h #define __lib_base_etpm_h -#include -#include - #ifndef SWIG #define TPMD_SOCKET "/var/run/tpmd_socket" #endif -class eTPM: public Object, public iObject +#include + +class eTPM { - DECLARE_REF(eTPM); #ifndef SWIG int fd; unsigned char level2_cert[210]; @@ -26,9 +24,9 @@ class eTPM: public Object, public iObject TPMD_CMD_APP_CERT = 0x0004, }; - bool send_cmd(enum tpmd_cmd cmd, const void *data, unsigned int len); - void *recv_cmd(unsigned int *tag, unsigned int *len); - void parse_data(const unsigned char *data, unsigned int datalen); + 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: @@ -39,8 +37,8 @@ public: TPMD_DT_LEVEL2_CERT = 0x04, TPMD_DT_LEVEL3_CERT = 0x05 }; - PyObject *getCert(cert_type type); - PyObject *challenge(PyObject *rnd); + std::string getCert(cert_type type); + std::string challenge(std::string rnd); }; #endif // __lib_base_etpm_h -- cgit v1.2.3