mirror of https://github.com/xemu-project/xemu.git
tpm-passthrough: move reusable code to utils
Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
parent
d0c519bdff
commit
4a3d80980e
|
@ -68,27 +68,6 @@ typedef struct TPMPassthruState TPMPassthruState;
|
||||||
|
|
||||||
static void tpm_passthrough_cancel_cmd(TPMBackend *tb);
|
static void tpm_passthrough_cancel_cmd(TPMBackend *tb);
|
||||||
|
|
||||||
static int tpm_passthrough_unix_write(int fd, const uint8_t *buf, uint32_t len)
|
|
||||||
{
|
|
||||||
int ret, remain;
|
|
||||||
|
|
||||||
remain = len;
|
|
||||||
while (remain > 0) {
|
|
||||||
ret = write(fd, buf, remain);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (errno != EINTR && errno != EAGAIN) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else if (ret == 0) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
buf += ret;
|
|
||||||
remain -= ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return len - remain;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tpm_passthrough_unix_read(int fd, uint8_t *buf, uint32_t len)
|
static int tpm_passthrough_unix_read(int fd, uint8_t *buf, uint32_t len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -102,45 +81,12 @@ static int tpm_passthrough_unix_read(int fd, uint8_t *buf, uint32_t len)
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t tpm_passthrough_get_size_from_buffer(const uint8_t *buf)
|
|
||||||
{
|
|
||||||
struct tpm_resp_hdr *resp = (struct tpm_resp_hdr *)buf;
|
|
||||||
|
|
||||||
return be32_to_cpu(resp->len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write an error message in the given output buffer.
|
|
||||||
*/
|
|
||||||
static void tpm_write_fatal_error_response(uint8_t *out, uint32_t out_len)
|
|
||||||
{
|
|
||||||
if (out_len >= sizeof(struct tpm_resp_hdr)) {
|
|
||||||
struct tpm_resp_hdr *resp = (struct tpm_resp_hdr *)out;
|
|
||||||
|
|
||||||
resp->tag = cpu_to_be16(TPM_TAG_RSP_COMMAND);
|
|
||||||
resp->len = cpu_to_be32(sizeof(struct tpm_resp_hdr));
|
|
||||||
resp->errcode = cpu_to_be32(TPM_FAIL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool tpm_passthrough_is_selftest(const uint8_t *in, uint32_t in_len)
|
|
||||||
{
|
|
||||||
struct tpm_req_hdr *hdr = (struct tpm_req_hdr *)in;
|
|
||||||
|
|
||||||
if (in_len >= sizeof(*hdr)) {
|
|
||||||
return (be32_to_cpu(hdr->ordinal) == TPM_ORD_ContinueSelfTest);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
|
static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
|
||||||
const uint8_t *in, uint32_t in_len,
|
const uint8_t *in, uint32_t in_len,
|
||||||
uint8_t *out, uint32_t out_len,
|
uint8_t *out, uint32_t out_len,
|
||||||
bool *selftest_done)
|
bool *selftest_done)
|
||||||
{
|
{
|
||||||
int ret;
|
ssize_t ret;
|
||||||
bool is_selftest;
|
bool is_selftest;
|
||||||
const struct tpm_resp_hdr *hdr;
|
const struct tpm_resp_hdr *hdr;
|
||||||
|
|
||||||
|
@ -148,9 +94,9 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
|
||||||
tpm_pt->tpm_executing = true;
|
tpm_pt->tpm_executing = true;
|
||||||
*selftest_done = false;
|
*selftest_done = false;
|
||||||
|
|
||||||
is_selftest = tpm_passthrough_is_selftest(in, in_len);
|
is_selftest = tpm_util_is_selftest(in, in_len);
|
||||||
|
|
||||||
ret = tpm_passthrough_unix_write(tpm_pt->tpm_fd, in, in_len);
|
ret = qemu_write_full(tpm_pt->tpm_fd, (const void *)in, (size_t)in_len);
|
||||||
if (ret != in_len) {
|
if (ret != in_len) {
|
||||||
if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
|
if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
|
||||||
error_report("tpm_passthrough: error while transmitting data "
|
error_report("tpm_passthrough: error while transmitting data "
|
||||||
|
@ -170,7 +116,7 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
|
||||||
strerror(errno), errno);
|
strerror(errno), errno);
|
||||||
}
|
}
|
||||||
} else if (ret < sizeof(struct tpm_resp_hdr) ||
|
} else if (ret < sizeof(struct tpm_resp_hdr) ||
|
||||||
tpm_passthrough_get_size_from_buffer(out) != ret) {
|
be32_to_cpu(((struct tpm_resp_hdr *)out)->len) != ret) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
error_report("tpm_passthrough: received invalid response "
|
error_report("tpm_passthrough: received invalid response "
|
||||||
"packet from TPM");
|
"packet from TPM");
|
||||||
|
@ -183,7 +129,7 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
|
||||||
|
|
||||||
err_exit:
|
err_exit:
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
tpm_write_fatal_error_response(out, out_len);
|
tpm_util_write_fatal_error_response(out, out_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
tpm_pt->tpm_executing = false;
|
tpm_pt->tpm_executing = false;
|
||||||
|
|
|
@ -23,6 +23,31 @@
|
||||||
#include "tpm_util.h"
|
#include "tpm_util.h"
|
||||||
#include "tpm_int.h"
|
#include "tpm_int.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write an error message in the given output buffer.
|
||||||
|
*/
|
||||||
|
void tpm_util_write_fatal_error_response(uint8_t *out, uint32_t out_len)
|
||||||
|
{
|
||||||
|
if (out_len >= sizeof(struct tpm_resp_hdr)) {
|
||||||
|
struct tpm_resp_hdr *resp = (struct tpm_resp_hdr *)out;
|
||||||
|
|
||||||
|
resp->tag = cpu_to_be16(TPM_TAG_RSP_COMMAND);
|
||||||
|
resp->len = cpu_to_be32(sizeof(struct tpm_resp_hdr));
|
||||||
|
resp->errcode = cpu_to_be32(TPM_FAIL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_len)
|
||||||
|
{
|
||||||
|
struct tpm_req_hdr *hdr = (struct tpm_req_hdr *)in;
|
||||||
|
|
||||||
|
if (in_len >= sizeof(*hdr)) {
|
||||||
|
return (be32_to_cpu(hdr->ordinal) == TPM_ORD_ContinueSelfTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A basic test of a TPM device. We expect a well formatted response header
|
* A basic test of a TPM device. We expect a well formatted response header
|
||||||
* (error response is fine) within one second.
|
* (error response is fine) within one second.
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
|
|
||||||
#include "sysemu/tpm_backend.h"
|
#include "sysemu/tpm_backend.h"
|
||||||
|
|
||||||
|
void tpm_util_write_fatal_error_response(uint8_t *out, uint32_t out_len);
|
||||||
|
|
||||||
|
bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_len);
|
||||||
|
|
||||||
int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version);
|
int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version);
|
||||||
|
|
||||||
#endif /* TPM_TPM_UTIL_H */
|
#endif /* TPM_TPM_UTIL_H */
|
||||||
|
|
Loading…
Reference in New Issue