Add TPM support
PATCH 1/1 Add TPM support
This patch adds support for an Atmel TPM chip.
Background: TPMs are rather complex chips, supporting many commands and implementing complex crypto protocols like Direct Anonymous Attestation (DAA). Therefore, this patch does not directly implement a TPM chip, but instead utilizes the TPM emulator project (http://tpm-emulator.berlios.de/).
The TPM emulator can be run as a daemon, communicating through a unix domain socket.
This patch adds a "-tpm path" parameter to qemu, where "path" is the unix domain socket of the TPM emulator. If the parameter is given, the chip is registered in the emulated system. Otherwise, behaviour is unchanged.
The interface presented inside qemu is that of an Atmel TPM chip, simply because there is a Linux driver for this chip and the interface is very simple. I do not own any TPM chip, therefore the interface was written purely by looking at the Linux driver.
Use case: This patch makes it possible to experiment with software like IBMs Integrity Measurement Architecture (IMA), without having an actual TPM (this patch was developed for a demonstration involving IMA, among other things). It should also be possible to use Microsofts BitLocker technology, although this hasn't been tested yet.
--- Makefile.target | 3 + hw/tpm.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ vl.c | 12 +++ vl.h | 4 + 4 files changed, 238 insertions(+), 0 deletions(-) create mode 100644 hw/tpm.c
Makefile.target +3 -0
@@ -460,6 +460,9 @@ VL_OBJS += ne2000.o VL_OBJS += pcnet.o VL_OBJS += rtl8139.o +# TPM device +VL_OBJS += tpm.o + ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
hw/tpm.c new file +219 -0
219 lines not on this page · raw message
vl.c +12 -0
@@ -218,6 +218,7 @@ int alt_grab = 0;unsigned int nb_prom_envs =0 ;const char *prom_envs[MAX_PROM_ENVS ];#endif +int tpm_enabled =0 ;#define TFR (expr) do { if ((expr) != -1) break; } while (errno == EINTR)
@@ -7107,6 +7108,8 @@ static void help(int exitcode)#endif "-clock force the use of the given methods for timer alarm.\n" " To see what timers are available use -clock help\n" +"-tpm path enable TPM support inside qemu and connect to a tpm\n" +" emulator on the given path\n" "\n" "During emulation, the following keys are useful:\n" "ctrl-alt-f toggle full screen\n"
@@ -7207,6 +7210,7 @@ enum { QEMU_OPTION_prom_env, QEMU_OPTION_old_param, QEMU_OPTION_clock, + QEMU_OPTION_tpm, }; typedef struct QEMUOption {
@@ -7313,6 +7317,7 @@ const QEMUOption qemu_options[] = { { "old-param", 0, QEMU_OPTION_old_param }, #endif { "clock", HAS_ARG, QEMU_OPTION_clock }, + { "tpm", HAS_ARG, QEMU_OPTION_tpm }, { NULL }, };
@@ -8097,6 +8102,10 @@ int main(int argc, char **argv)case QEMU_OPTION_clock:configure_alarms (optarg);break ; +case QEMU_OPTION_tpm: + tpm_enabled =1 ; +tpm_configure (optarg); +break ; } } }
@@ -8427,6 +8436,9 @@ int main(int argc, char **argv) } } +if (tpm_enabled) +tpm_register (); +if (display_state.dpy_refresh) { display_state.gui_timer =qemu_new_timer (rt_clock, gui_update, &display_state);qemu_mod_timer (display_state.gui_timer,qemu_get_clock (rt_clock));
vl.h +4 -0
@@ -1716,4 +1716,8 @@ void readline_start(const char *prompt, int is_password,void kqemu_record_dump (void ); +/* tpm.c */ +void tpm_configure (const char * tpm_socket); +void tpm_register (); +#endif /* VL_H */
Quoted 57 lines · Thomas Bleher
This patch adds support for an Atmel TPM chip.
Background: TPMs are rather complex chips, supporting many commands and implementing complex crypto protocols like Direct Anonymous Attestation (DAA). Therefore, this patch does not directly implement a TPM chip, but instead utilizes the TPM emulator project (http://tpm-emulator.berlios.de/).
The TPM emulator can be run as a daemon, communicating through a unix domain socket.This patch adds a "-tpm path" parameter to qemu, where "path" is the unix domain socket of the TPM emulator. If the parameter is given, the chip is registered in the emulated system. Otherwise, behaviour is unchanged.
The interface presented inside qemu is that of an Atmel TPM chip, simply because there is a Linux driver for this chip and the interface is very simple. I do not own any TPM chip, therefore the interface was written purely by looking at the Linux driver.
Use case: This patch makes it possible to experiment with software like IBMs Integrity Measurement Architecture (IMA), without having an actual TPM (this patch was developed for a demonstration involving IMA, among other things). It should also be possible to use Microsofts BitLocker technology, although this hasn't been tested yet.
--- Makefile.target | 3 + hw/tpm.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ vl.c | 12 +++ vl.h | 4 + 4 files changed, 238 insertions(+), 0 deletions(-) create mode 100644 hw/tpm.cMakefile.target +3
-0@@ -460,6 +460,9 @@ VL_OBJS += ne2000.o VL_OBJS += pcnet.o VL_OBJS += rtl8139.o +# TPM device +VL_OBJS += tpm.o + ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)hw/tpm.c new file +5
-0@@ -0,0 +1,219 @@ +/* +* TPM emulation +* Written by Thomas Bleher <[email protected]>. +* +* This driver emulates a TPM chip. TPM chips are quite complex, and a TPM
hw/tpm.c line 15
Quoted 10 lines
hw/tpm.c new file +10
-0+* emulator already exists, therefore this driver just connects to this +* emulator and forwards all the data. For the TPM emulator project, see +* http://tpm-emulator.berlios.de/ +* +* The author does not own any TPM chip himself, so the Linux Kernel driver for +* Atmel TPM chips was taken as a reference. The code works fine with the Linux +* driver, but no tests have been done on other operating systems. +* +* Some structures are copied from the Linux Kernel source code. +*/
So the License of this file is "GPL, Version 2"? The license should be mentioned in the comment.
Thiemo
This patch adds support for an Atmel TPM chip.
Background: TPMs are rather complex chips, supporting many commands and implementing complex crypto protocols like Direct Anonymous Attestation (DAA). Therefore, this patch does not directly implement a TPM chip, but instead utilizes the TPM emulator project (http://tpm-emulator.berlios.de/).
The TPM emulator can be run as a daemon, communicating through a unix domain socket.
This patch adds a "-tpm path" parameter to qemu, where "path" is the unix domain socket of the TPM emulator. If the parameter is given, the chip is registered in the emulated system. Otherwise, behaviour is unchanged.
The interface presented inside qemu is that of an Atmel TPM chip, simply because there is a Linux driver for this chip and the interface is very simple. I do not own any TPM chip, therefore the interface was written purely by looking at the Linux driver.
Use case: This patch makes it possible to experiment with software like IBMs Integrity Measurement Architecture (IMA), without having an actual TPM (this patch was developed for a demonstration involving IMA, among other things). It should also be possible to use Microsofts BitLocker technology, although this hasn't been tested yet.
---
Quoted 14 lines · Thiemo Seufer
Quoted 13 lines · Thomas Bleher
hw/tpm.c new file +10
-0@@ -0,0 +1,219 @@ +/* +* TPM emulation +* Written by Thomas Bleher <[email protected]>. +* +* This driver emulates a TPM chip. TPM chips are quite complex, and a TPM +* emulator already exists, therefore this driver just connects to this +* emulator and forwards all the data. For the TPM emulator project, see +* http://tpm-emulator.berlios.de/ +* +* The author does not own any TPM chip himself, so the Linux Kernel driver for
Quoted 8 lines
hw/tpm.c line 15
Quoted 5 lines
hw/tpm.c new file +5
-0+* Atmel TPM chips was taken as a reference. The code works fine with the Linux +* driver, but no tests have been done on other operating systems. +* +* Some structures are copied from the Linux Kernel source code. +*/ So the License of this file is "GPL, Version 2"? The license should be mentioned in the comment.
I think that the parts I copied are not copyrightable, as I only copied the two enums (I didn't copy any structures, the comment was wrong) and, modulo naming, I see no other way to implement this.
So I would be willing to license this under a more liberal license, but to be on the safe side, GNU GPLv2 is the best choice. Updated patch below.
Makefile.target | 3 + hw/tpm.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ vl.c | 12 +++ vl.h | 4 + 4 files changed, 239 insertions(+), 0 deletions(-) create mode 100644 hw/tpm.c
Makefile.target +3 -0
@@ -460,6 +460,9 @@ VL_OBJS += ne2000.o VL_OBJS += pcnet.o VL_OBJS += rtl8139.o +# TPM device +VL_OBJS += tpm.o + ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
hw/tpm.c new file +220 -0
220 lines not on this page · raw message
vl.c +12 -0
@@ -218,6 +218,7 @@ int alt_grab = 0;unsigned int nb_prom_envs =0 ;const char *prom_envs[MAX_PROM_ENVS ];#endif +int tpm_enabled =0 ;#define TFR (expr) do { if ((expr) != -1) break; } while (errno == EINTR)
@@ -7107,6 +7108,8 @@ static void help(int exitcode)#endif "-clock force the use of the given methods for timer alarm.\n" " To see what timers are available use -clock help\n" +"-tpm path enable TPM support inside qemu and connect to a tpm\n" +" emulator on the given path\n" "\n" "During emulation, the following keys are useful:\n" "ctrl-alt-f toggle full screen\n"
@@ -7207,6 +7210,7 @@ enum { QEMU_OPTION_prom_env, QEMU_OPTION_old_param, QEMU_OPTION_clock, + QEMU_OPTION_tpm, }; typedef struct QEMUOption {
@@ -7313,6 +7317,7 @@ const QEMUOption qemu_options[] = { { "old-param", 0, QEMU_OPTION_old_param }, #endif { "clock", HAS_ARG, QEMU_OPTION_clock }, + { "tpm", HAS_ARG, QEMU_OPTION_tpm }, { NULL }, };
@@ -8097,6 +8102,10 @@ int main(int argc, char **argv)case QEMU_OPTION_clock:configure_alarms (optarg);break ; +case QEMU_OPTION_tpm: + tpm_enabled =1 ; +tpm_configure (optarg); +break ; } } }
@@ -8427,6 +8436,9 @@ int main(int argc, char **argv) } } +if (tpm_enabled) +tpm_register (); +if (display_state.dpy_refresh) { display_state.gui_timer =qemu_new_timer (rt_clock, gui_update, &display_state);qemu_mod_timer (display_state.gui_timer,qemu_get_clock (rt_clock));
vl.h +4 -0
@@ -1716,4 +1716,8 @@ void readline_start(const char *prompt, int is_password,void kqemu_record_dump (void ); +/* tpm.c */ +void tpm_configure (const char * tpm_socket); +void tpm_register (); +#endif /* VL_H */
Quoted 50 lines · Thomas Bleher
This patch adds support for an Atmel TPM chip.
Background: TPMs are rather complex chips, supporting many commands and implementing complex crypto protocols like Direct Anonymous Attestation (DAA). Therefore, this patch does not directly implement a TPM chip, but instead utilizes the TPM emulator project (http://tpm-emulator.berlios.de/).
The TPM emulator can be run as a daemon, communicating through a unix domain socket.This patch adds a "-tpm path" parameter to qemu, where "path" is the unix domain socket of the TPM emulator. If the parameter is given, the chip is registered in the emulated system. Otherwise, behaviour is unchanged.
The interface presented inside qemu is that of an Atmel TPM chip, simply because there is a Linux driver for this chip and the interface is very simple. I do not own any TPM chip, therefore the interface was written purely by looking at the Linux driver.
Use case: This patch makes it possible to experiment with software like IBMs Integrity Measurement Architecture (IMA), without having an actual TPM (this patch was developed for a demonstration involving IMA, among other things). It should also be possible to use Microsofts BitLocker technology, although this hasn't been tested yet.
---
Quoted 14 lines · Thiemo Seufer
Quoted 13 lines · Thomas Bleher
hw/tpm.c new file +10
-0@@ -0,0 +1,219 @@ +/* +* TPM emulation +* Written by Thomas Bleher <[email protected]>. +* +* This driver emulates a TPM chip. TPM chips are quite complex, and a TPM +* emulator already exists, therefore this driver just connects to this +* emulator and forwards all the data. For the TPM emulator project, see +* http://tpm-emulator.berlios.de/ +* +* The author does not own any TPM chip himself, so the Linux Kernel driver for Quoted 8 lines
hw/tpm.c line 16
Quoted 5 lines
hw/tpm.c new file +5
-0+* Atmel TPM chips was taken as a reference. The code works fine with the Linux +* driver, but no tests have been done on other operating systems. +* +* Some structures are copied from the Linux Kernel source code. +*/ So the License of this file is "GPL, Version 2"? The license should be mentioned in the comment.
Quoted 3 lines
I think that the parts I copied are not copyrightable, as I only copied the two enums (I didn't copy any structures, the comment was wrong) and, modulo naming, I see no other way to implement this.
Ok, so the Kernel license isn't relevant here.
Quoted 2 lines
So I would be willing to license this under a more liberal license, but to be on the safe side, GNU GPLv2 is the best choice.
I didn't intend to enforce GPL licensing, I just concluded from the description that the patch would include substantial parts of kernel source code. Since this isn't the case, feel free to choose your preferred license for it.
Thiemo
Quoted 31 lines · Thiemo Seufer
Quoted 24 lines · Thomas Bleher
Quoted 14 lines · Thiemo Seufer
Quoted 13 lines · Thomas Bleher
hw/tpm.c new file +10
-0@@ -0,0 +1,219 @@ +/* +* TPM emulation +* Written by Thomas Bleher <[email protected]>. +* +* This driver emulates a TPM chip. TPM chips are quite complex, and a TPM +* emulator already exists, therefore this driver just connects to this +* emulator and forwards all the data. For the TPM emulator project, see +* http://tpm-emulator.berlios.de/ +* +* The author does not own any TPM chip himself, so the Linux Kernel driver for Quoted 8 lines
hw/tpm.c line 16
Quoted 5 lines
hw/tpm.c new file +5
-0+* Atmel TPM chips was taken as a reference. The code works fine with the Linux +* driver, but no tests have been done on other operating systems. +* +* Some structures are copied from the Linux Kernel source code. +*/ So the License of this file is "GPL, Version 2"? The license should be mentioned in the comment.
Quoted 3 lines
I think that the parts I copied are not copyrightable, as I only copied the two enums (I didn't copy any structures, the comment was wrong) and, modulo naming, I see no other way to implement this.
Ok, so the Kernel license isn't relevant here.
Quoted 7 lines
Quoted 2 lines
So I would be willing to license this under a more liberal license, but to be on the safe side, GNU GPLv2 is the best choice.
I didn't intend to enforce GPL licensing, I just concluded from the description that the patch would include substantial parts of kernel source code. Since this isn't the case, feel free to choose your preferred license for it.
Is there a preferred license for qemu? I see that the code as a whole is licensed under the GPLv2, but some code is under the LGPL or some BSD license. I'm willing to license it under whatever license suits qemu best.
Regards,
Thomas
Quoted 40 lines · Thomas Bleher
Quoted 31 lines · Thiemo Seufer
Quoted 24 lines · Thomas Bleher
Quoted 14 lines · Thiemo Seufer
Quoted 13 lines · Thomas Bleher
hw/tpm.c new file +10
-0@@ -0,0 +1,219 @@ +/* +* TPM emulation +* Written by Thomas Bleher <[email protected]>. +* +* This driver emulates a TPM chip. TPM chips are quite complex, and a TPM +* emulator already exists, therefore this driver just connects to this +* emulator and forwards all the data. For the TPM emulator project, see +* http://tpm-emulator.berlios.de/ +* +* The author does not own any TPM chip himself, so the Linux Kernel driver for Quoted 8 lines
hw/tpm.c line 16
Quoted 5 lines
hw/tpm.c new file +5
-0+* Atmel TPM chips was taken as a reference. The code works fine with the Linux +* driver, but no tests have been done on other operating systems. +* +* Some structures are copied from the Linux Kernel source code. +*/ So the License of this file is "GPL, Version 2"? The license should be mentioned in the comment.
Quoted 3 lines
I think that the parts I copied are not copyrightable, as I only copied the two enums (I didn't copy any structures, the comment was wrong) and, modulo naming, I see no other way to implement this.
Ok, so the Kernel license isn't relevant here.
Quoted 7 lines
Quoted 2 lines
So I would be willing to license this under a more liberal license, but to be on the safe side, GNU GPLv2 is the best choice.
I didn't intend to enforce GPL licensing, I just concluded from the description that the patch would include substantial parts of kernel source code. Since this isn't the case, feel free to choose your preferred license for it.
Quoted 4 lines
Is there a preferred license for qemu? I see that the code as a whole is licensed under the GPLv2, but some code is under the LGPL or some BSD license. I'm willing to license it under whatever license suits qemu best.
Thiemo Seufer told me that GPLv2 is fine for qemu, therefore I'd like to ask that this patch be included in qemu as I posted it (the second version with the clarified GPLv2 license).
Thanks,
Thomas Bleher
Quoted 3 lines · Thomas Bleher
Thiemo Seufer told me that GPLv2 is fine for qemu, therefore I'd like to ask that this patch be included in qemu as I posted it (the second version with the clarified GPLv2 license).
I prefer that a BSD style license is used, especially if the code just contains wrappers.
Regards,
Fabrice.
Quoted 7 lines · Fabrice Bellard
Quoted 3 lines · Thomas Bleher
Thiemo Seufer told me that GPLv2 is fine for qemu, therefore I'd like to ask that this patch be included in qemu as I posted it (the second version with the clarified GPLv2 license).
I prefer that a BSD style license is used, especially if the code just contains wrappers.
Fine with me, too.
Would the attached patch be acceptable?
Regards,
Thomas
This patch adds support for an Atmel TPM chip.
Background: TPMs are rather complex chips, supporting many commands and implementing complex crypto protocols like Direct Anonymous Attestation (DAA). Therefore, this patch does not directly implement a TPM chip, but instead utilizes the TPM emulator project (http://tpm-emulator.berlios.de/).
The TPM emulator can be run as a daemon, communicating through a unix domain socket.
This patch adds a "-tpm path" parameter to qemu, where "path" is the unix domain socket of the TPM emulator. If the parameter is given, the chip is registered in the emulated system. Otherwise, behaviour is unchanged.
The interface presented inside qemu is that of an Atmel TPM chip, simply because there is a Linux driver for this chip and the interface is very simple. I do not own any TPM chip, therefore the interface was written purely by looking at the Linux driver.
Use case: This patch makes it possible to experiment with software like IBMs Integrity Measurement Architecture (IMA), without having an actual TPM (this patch was developed for a demonstration involving IMA, among other things). It should also be possible to use Microsofts BitLocker technology, although this hasn't been tested yet.
Makefile.target | 3 hw/tpm.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vl.c | 12 ++ vl.h | 4 4 files changed, 258 insertions(+)
Makefile.target +3 -0
@@ -460,6 +460,9 @@ VL_OBJS += ne2000.o VL_OBJS += pcnet.o VL_OBJS += rtl8139.o +# TPM device +VL_OBJS += tpm.o + ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
hw/tpm.c new file +240 -0
240 lines not on this page · raw message
vl.c +12 -0
@@ -218,6 +218,7 @@ int alt_grab = 0;unsigned int nb_prom_envs =0 ;const char *prom_envs[MAX_PROM_ENVS ];#endif +int tpm_enabled =0 ;#define TFR (expr) do { if ((expr) != -1) break; } while (errno == EINTR)
@@ -7107,6 +7108,8 @@ static void help(int exitcode)#endif "-clock force the use of the given methods for timer alarm.\n" " To see what timers are available use -clock help\n" +"-tpm path enable TPM support inside qemu and connect to a tpm\n" +" emulator on the given path\n" "\n" "During emulation, the following keys are useful:\n" "ctrl-alt-f toggle full screen\n"
@@ -7207,6 +7210,7 @@ enum { QEMU_OPTION_prom_env, QEMU_OPTION_old_param, QEMU_OPTION_clock, + QEMU_OPTION_tpm, }; typedef struct QEMUOption {
@@ -7313,6 +7317,7 @@ const QEMUOption qemu_options[] = { { "old-param", 0, QEMU_OPTION_old_param }, #endif { "clock", HAS_ARG, QEMU_OPTION_clock }, + { "tpm", HAS_ARG, QEMU_OPTION_tpm }, { NULL }, };
@@ -8097,6 +8102,10 @@ int main(int argc, char **argv)case QEMU_OPTION_clock:configure_alarms (optarg);break ; +case QEMU_OPTION_tpm: + tpm_enabled =1 ; +tpm_configure (optarg); +break ; } } }
@@ -8427,6 +8436,9 @@ int main(int argc, char **argv) } } +if (tpm_enabled) +tpm_register (); +if (display_state.dpy_refresh) { display_state.gui_timer =qemu_new_timer (rt_clock, gui_update, &display_state);qemu_mod_timer (display_state.gui_timer,qemu_get_clock (rt_clock));
vl.h +4 -0
@@ -1716,4 +1716,8 @@ void readline_start(const char *prompt, int is_password,void kqemu_record_dump (void ); +/* tpm.c */ +void tpm_configure (const char * tpm_socket); +void tpm_register (); +#endif /* VL_H */
Quoted 9 lines · Thomas Bleher
Quoted 6 lines · Fabrice Bellard
Quoted 3 lines · Thomas Bleher
Thiemo Seufer told me that GPLv2 is fine for qemu, therefore I'd like to ask that this patch be included in qemu as I posted it (the second version with the clarified GPLv2 license).
I prefer that a BSD style license is used, especially if the code just contains wrappers.
Fine with me, too.
OK.
hw/tpm.c line 114
Quoted 5 lines
hw/tpm.c new file +5
-0+ result =write (s->tpm_fd, s->send_data, s->send_data_index); +if (result < s->send_data_index) { +fprintf (stderr,"WARNING: Failed to write data to tpm!\n" ); +return ATML_STATUS_BUSY ; + }
You should handle EINTR and EAGAIN.
hw/tpm.c line 122
Quoted 8 lines
hw/tpm.c new file +8
-0+ s->send_data_index =0 ; + s->recv_data_pos =0 ; + s->recv_data_length =0 ; + s->data_to_send =0 ; + s->data_to_recv =1 ; + } +if (s->data_to_recv) { +if (poll (&(s->tpm_poll),1 ,0 ) >0 ) {
poll is not needed as read will block.
hw/tpm.c line 127
Quoted 5 lines
hw/tpm.c new file +5
-0+ result =read (s->tpm_fd, s->recv_data,2048 ); +if (result <6 ) {// a minimal packet is 6 bytes long +fprintf (stderr,"WARNING: Not enough data from tpm!\n" ); +return ATML_STATUS_BUSY ; + }
same comment as write().
hw/tpm.c line 200
Quoted 3 lines
hw/tpm.c new file +3
-0+ res =connect (sock, (struct sockaddr *)&addr,sizeof (struct sockaddr_un )); +if (res <0 ) +return -1 ;
same comment for EINTR.
+/* should be called first, initializes all structures and connects to the external emulator */
+void tpm_configure(const char* tpm_socket)
+{
Suppress this function (cf tpm_register).
hw/tpm.c line 227
Quoted 2 lines
hw/tpm.c new file +2
-0+/* split of from tpm_configure() so the configuration can be called earlier */ +void tpm_register ()
Ansi C requires void in parameters. Allocate the state and return it. Suppress the global variable tpm_state. Pass the path to this function and suppress the configure function. Add a global variable for the path and register the device if it is not NULL.
Regards,
Fabrice.
Quoted 43 lines · Fabrice Bellard
Review
Quoted 7 lines · Thomas Bleher
Quoted 1 line · Fabrice Bellard
Thomas Bleher wrote:
(quoted diff) +5
-0+ result = write(s->tpm_fd, s->send_data, s->send_data_index); + if (result < s->send_data_index) { + fprintf(stderr, "WARNING: Failed to write data to tpm!\n"); + return ATML_STATUS_BUSY; + }You should handle EINTR and EAGAIN.
Review
Quoted 8 lines
(quoted diff) +8
-0+ s->send_data_index = 0; + s->recv_data_pos = 0; + s->recv_data_length = 0; + s->data_to_send = 0; + s->data_to_recv = 1; + } + if (s->data_to_recv) { + if (poll(&(s->tpm_poll), 1, 0) > 0) {poll is not needed as read will block.
Review
Quoted 5 lines
(quoted diff) +5
-0+ result = read(s->tpm_fd, s->recv_data, 2048); + if (result < 6) { // a minimal packet is 6 bytes long + fprintf(stderr, "WARNING: Not enough data from tpm!\n"); + return ATML_STATUS_BUSY; + }same comment as
write().Review
Quoted 3 lines
(quoted diff) +3
-0+ res = connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)); + if (res < 0) + return -1;same comment for EINTR.
+/* should be called first, initializes all structures and connects to the external emulator */
(quoted diff) +2
-0+void tpm_configure(const char* tpm_socket) +{Suppress this function (cf
tpm_register).
Quoted 7 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+/* split of from tpm_configure() so the configuration can be called earlier */ +void tpm_register()Ansi C requires void in parameters. Allocate the state and return it. Suppress the global variable
tpm_state. Pass the path to this function and suppress the configure function. Add a global variable for the path and register the device if it is not NULL.
Thank you for the review!
An updated patch is appended. The patch has been tested using a Linux client with IMA added.
Thomas
Author: Thomas Bleher <[email protected]> Date: Wed Nov 7 12:27:14 2007 +0100
This patch adds support for an Atmel TPM chip.
Background: TPMs are rather complex chips, supporting many commands and implementing complex crypto protocols like Direct Anonymous Attestation (DAA). Therefore, this patch does not directly implement a TPM chip, but instead utilizes the TPM emulator project (http://tpm-emulator.berlios.de/).
The TPM emulator can be run as a daemon, communicating through a unix domain socket.
This patch adds a "-tpm path" parameter to qemu, where "path" is the unix domain socket of the TPM emulator. If the parameter is given, the chip is registered in the emulated system. Otherwise, behaviour is unchanged.
The interface presented inside qemu is that of an Atmel TPM chip, simply because there is a Linux driver for this chip and the interface is very simple. I do not own any TPM chip, therefore the interface was written purely by looking at the Linux driver.
Use case: This patch makes it possible to experiment with software like IBMs Integrity Measurement Architecture (IMA), without having an actual TPM (this patch was developed for a demonstration involving IMA, among other things). It should also be possible to use Microsofts BitLocker technology, although this hasn't been tested yet.
Makefile.target +3 -0
@@ -460,6 +460,9 @@ VL_OBJS += ne2000.o VL_OBJS += pcnet.o VL_OBJS += rtl8139.o +# TPM device +VL_OBJS += tpm.o + ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
hw/tpm.c new file +228 -0
228 lines not on this page · raw message
vl.c +15 -0
@@ -223,6 +223,7 @@ int alt_grab = 0;unsigned int nb_prom_envs =0 ;const char *prom_envs[MAX_PROM_ENVS ];#endif +const char *tpm_path;#define TFR (expr) do { if ((expr) != -1) break; } while (errno == EINTR)
@@ -7112,6 +7113,8 @@ static void help(int exitcode)#endif "-clock force the use of the given methods for timer alarm.\n" " To see what timers are available use -clock help\n" +"-tpm path enable TPM support inside qemu and connect to a tpm\n" +" emulator on the given path\n" "\n" "During emulation, the following keys are useful:\n" "ctrl-alt-f toggle full screen\n"
@@ -7212,6 +7215,7 @@ enum { QEMU_OPTION_prom_env, QEMU_OPTION_old_param, QEMU_OPTION_clock, + QEMU_OPTION_tpm, }; typedef struct QEMUOption {
@@ -7318,6 +7322,7 @@ const QEMUOption qemu_options[] = { { "old-param", 0, QEMU_OPTION_old_param }, #endif { "clock", HAS_ARG, QEMU_OPTION_clock }, + { "tpm", HAS_ARG, QEMU_OPTION_tpm }, { NULL }, };
@@ -8107,6 +8112,9 @@ int main(int argc, char **argv)case QEMU_OPTION_clock:configure_alarms (optarg);break ; +case QEMU_OPTION_tpm: + tpm_path = optarg; +break ; } } }
@@ -8439,6 +8447,13 @@ int main(int argc, char **argv) } } +if (tpm_path) { +if (!tpm_register (tpm_path)) { +perror ("Failed to create connection to the TPM emulator" ); +exit (1 ); + } + } +if (display_state.dpy_refresh) { display_state.gui_timer =qemu_new_timer (rt_clock, gui_update, &display_state);qemu_mod_timer (display_state.gui_timer,qemu_get_clock (rt_clock));
vl.h +4 -0
@@ -1720,4 +1720,8 @@ void readline_start(const char *prompt, int is_password,void kqemu_record_dump (void ); +/* tpm.c */ +typedef struct TPMState TPMState ; +TPMState *tpm_register (const char * tpm_socket); +#endif /* VL_H */
A few more remarks :
- tpm_register() must be called in hw/pc.c.
- you must also handle incomplete write and reads. Use something like unix_write() in vl.c and the equivalent for read.
- The code seems to be Unix specific so it must be disabled for win32.
Regards,
Fabrice.
Quoted 8 lines · Fabrice Bellard
A few more remarks :
-
tpm_register()must be called inhw/pc.c.- you must also handle incomplete write and reads. Use something like
unix_write()invl.cand the equivalent for read.- The code seems to be Unix specific so it must be disabled for win32.
Thank you for the comments. I had hoped to have some time this weekend to fix these issues, but this wasn't the case. I've put them on my TODO list and will resubmit once the issues are fixed.
Regards,
Thomas